Como se mencionó en el título, la opción set -o posix no parece estar funcionando en GNU / Linux Bash 5.0.17 (no estoy seguro de que esté específicamente relacionado con WSL2 Ubuntu 20.04 o cualquier cosa, pero lo señaló en caso de que sea Trabajando para otros en sus máquinas).

Puedo encenderlo y apagarlo:

$ set -o |grep posix
posix        off
$ set -o posix
$ set -o |grep posix
posix        on
$ set -o posix
$ set -o |grep posix
posix        off
$ set -o posix
$ set -o |grep posix
posix        on

Pero, por ejemplo, cuando estoy encendido, puedo hacer lo siguiente

$ set -o posix
$ set -o |grep posix
posix        on
$ type cd
cd is a shell builtin
$ cd /
$ ls
bin   dev  home  lib    lib64   lost+found  mnt  proc  run   snap  sys  usr
boot  etc  init  lib32  libx32  media       opt  root  sbin  srv   tmp  var
$ cd() { :; }
$ type cd
cd is a function
cd ()
{
    :
}
$ cd ~
$ ls
bin   dev  home  lib    lib64   lost+found  mnt  proc  run   snap  sys  usr
boot  etc  init  lib32  libx32  media       opt  root  sbin  srv   tmp  var
$ unset -f cd
$ cd ~
$ ls
Desktop  Documents  Downloads  Music  Pictures  Public  Templates  Videos

Soy capaz de anular todas las banderas especiales (incluyendo builtin y type!). Además, no soy root, pero solo en mi cuenta de usuario. ¿Alguien sabe lo que estoy haciendo mal?

ACTUALIZACIÓN:

@Shawn, @oguzismail, y @dan, todos dan la respuesta correcta a continuación: cd es un regular . Quería agregar alguna aclaración, ya que creo que será importante para los alumnos como yo:

@oguzismail apunta correctamente a la sección de scripting de shell clásico que explica que {{ X0}} es un regular incorporado:

Por esta razón, puede escribir una función llamada CD, y la cubierta encontrará su función primero, ya que el CD es un regular incorporado

  • Sección 7.9 (Pg. 261 en Kindle Edition)

Mi confusión vino de la declaración en el resumen:

Existen comandos incorporados ya sea porque cambian el estado interno de la carcasa y deben ser incorporados (como CD), o para la eficiencia (como la prueba).

  • (Sección 7 Resumen, Pg. 264 en Kindle Edition)

Aquí, cd es una incorporada, pero como los estados del autor anteriormente, es un regular . Tiene que ser un comando integrado en la cáscara porque el comando cambia el estado interno de la cáscara (es decir, cambia el directorio de trabajo actual / actual de la carcasa), pero puede ser un regular o especial integrado. Como menciona @dan, la POSIX IEEE STD 1003.1-2017 Estándar, Sección 2.14 lo define como un regular . (Durante al menos una de las razones por las cuales, Sección 7.9 de scripting de shell clásico muestra que Hacerlo permite que el programador personalice su comportamiento).

¡Aunque sea advertido! (NB = Nota Bene): Si elige sobrescribir cd con una función definida por el usuario, use command cd dentro de la definición de función donde desea cambiar de directorios. La función command se salta buscando funciones en el orden de búsqueda definido por POSIX de special built-ins --> functions --> regular built-ins --> external commands on $PATH. De lo contrario, si usa cd dentro de su función definida por el usuario cd, lo más probable es que termine con un bucle de recursión infinito. (Scripts de shell clásico también cubre este punto).

-1
A. Hendry 29 may. 2021 a las 01:16

2 respuestas

La mejor respuesta

set -o posix funciona bien:

  $ set -o posix
  $ set () { :; }
bash: `set': is a special builtin

cd no es un especial integrado, ni es builtin o type.

La lista de "Special BURTININS" es claramente definido en el Especificación POSIX.

Un "especial incorporado" es distinto de cualquier otro comando que una concha puede o no implementar como una incorporada.

1
dan 29 may. 2021 a las 13:58

La clave aquí es lo que bash considera un especial incorporado . Tuve que profundizar en la fuente para encontrar una lista:

/* The Posix.2 so-called `special' builtins. */
char *special_builtins[] =
{
  ":", ".", "source", "break", "continue", "eval", "exec", "exit",
  "export", "readonly", "return", "set", "shift", "times", "trap", "unset",
  (char *)NULL
};

Son también descrito en la documentación de POSIX como distinta desde incorporado regularmente.

Y de hecho...

$ bash --posix
bash-4.4$ break() { :; }
bash: `break': is a special builtin
bash-4.4$ type break
break is a special shell builtin
bash-4.4$ type cd
cd is a shell builtin

Tenga en cuenta la salida diferente de type para break y cd, porque este último no está en esa lista.

3
Shawn 29 may. 2021 a las 04:19