script opciones example linux shell centos6

linux - opciones - ¿Qué significa ${-#* i} en el script de shell?



menu de opciones en bash (3)

Vea la respuesta principal a ¿Qué significa “$ {- # * i}”! = “$ -” significa? en Unix y Linux por cuonglm :

$- son los indicadores de opción actuales establecidos por el propio shell, en la invocación o utilizando el comando incorporado en el set :

$ echo $- himBH $ set -a $ echo $- ahimBH

"${-#*i}" es una sintaxis para eliminar cadenas: (de la documentación de POSIX )

$ { parámetro # [ palabra ]}

Eliminar el patrón de prefijo más pequeño. La palabra se expandirá para producir un patrón. La expansión del parámetro dará como resultado un parámetro, con la parte más pequeña del prefijo que coincida con el patrón eliminado.

Si está presente, la palabra no comenzará con un '' # '' sin comillas.

$ { parámetro ## [ palabra ]}

Eliminar el patrón de prefijo más grande. La palabra se expandirá para producir un patrón. La expansión del parámetro dará como resultado un parámetro, con la porción más grande del prefijo emparejado por el patrón eliminado.

Entonces ${-#*i} elimina la cadena más corta hasta el primer carácter i :

enter code here $ echo "${-#*i}" mBH

En su caso, if [ "${-#*i}" != "$-" ] verifica si su shell es interactivo o no.

Hay un bucle for en el archivo /etc/profile en CentOS 6:

for i in /etc/profile.d/*.sh ; do if [ -r "$i" ]; then if [ "${-#*i}" != "$-" ]; then . "$i" else . "$i" >/dev/null 2>&1 fi fi done

¿Qué significa ${-#*i} en el bucle anterior para?
Gracias por cualquier ayuda.


$- significa banderas de concha.

${-#*i} significa indicadores de shell menos la primera coincidencia de *i .

Si estos dos no son iguales, entonces el shell se considera interactivo (el indicador i está presente).


tl; dr:

Condicional [ "${-#*i}" != "$-" ] evalúa como lógico verdadero si el shell actual es interactivo , en cuyo caso el código de salida se establece en 0 , lo que indica que es verdadero , lo que hace que las instrucciones adjuntas de if rama a ser ejecutada.

El condicional y el código de la pregunta en su conjunto utilizan intencionalmente solo la sintaxis y los comandos de lenguaje de shell compatibles con POSIX para que sean portátiles (funcionan con todos los shells compatibles con POSIX que pueden actuar como /bin/sh ).

Tenga en cuenta que si bash podría asumirse como shell, por ejemplo, el mismo condicional podría expresarse más fácilmente como
[[ $- == *i* ]]

Explicación

  • ${-#*i} es una expansión de parámetros que elimina el prefijo más corto ( # ) que coincide con el pattern *i del valor del parámetro nombrado $- (un parámetro llamado se denomina más comúnmente una variable ).

  • $- es un parámetro especial , que (enlace y énfasis añadido):

    se expande a los indicadores de option actuales (los nombres de opción de una sola letra concatenados en una cadena ) como se especifica en la invocación, por el comando incorporado especial del conjunto, o implícitamente por el shell.

  • Un shell interactivo agrega implícitamente el indicador de opción i al valor de $- ; en otras palabras: la presencia de la letra i en el valor de $- implica que el shell en cuestión es interactivo y, a la inversa, la ausencia de i implica que el shell no es interactivo .

  • Por lo tanto, en la expansión de parámetros ${-#*i} , el patrón *i solo coincidirá dentro del valor de $- si hay una i , y, si es así, al eliminar lo que *i coincide, devolverá una subcadena (sufijo , en este caso) de $- .
    En otras palabras: solo en una shell interactiva ${-#*i} no es igual a $- , porque en una shell no interactiva , debido a la ausencia de i , la expansión del parámetro no tiene efecto y los dos operandos son iguales.

Lo que hace el código en la pregunta como un todo :

En resumen: el código usa scripts de shell que encuentra en /etc/profile.d para inicializar el shell actual; más específicamente:

  • Los scripts (archivos denominados *.sh ) ubicados en el directorio /etc/profile.d que pueden ser leídos por el usuario actual ( -r ) se pasan a . (punto) utilidad una por una, en orden alfabético. La utilidad de puntos ejecuta los comandos de cada archivo en el shell actual , generalmente para definir alias, funciones y variables de entorno. Esto se conoce comúnmente como fuente de un archivo.

  • La salida producida por cada script de origen se maneja de manera diferente dependiendo de si el shell actual es interactivo o no:

    • shell interactivo : la salida se pasa (estará visible en el shell interactivo).

    • shell no interactivo : la salida se suprime ( >/dev/null 2>&1 es la forma compatible con POSIX de silenciar tanto la salida estándar como la salida estándar).