Pregunta

Además de los patrones básicos *, ? y [...], el shell Bash proporciona un patrón extendido búsqueda de operadores como !(pattern-list) ( "coincide con todos excepto uno de los patrones dados"). La opción del shell extglob necesita configurarse para utilizarlos. Un ejemplo:

~$ mkdir test ; cd test ; touch file1 file2 file3
~/test$ echo *
file1 file2 file3
~/test$ shopt -s extglob  # make sure extglob is set
~/test$ echo !(file2)
file1 file3

Si paso una expresión shell a un programa que se ejecuta en un sub-cáscara, el operador hace que un error. Aquí está una prueba que se ejecuta una sub-shell directamente (en este caso estoy ejecutando desde otro directorio para asegurarse de expansión no tenga lugar antes de tiempo):

~/test$ cd ..
~$ bash -c "cd test ; echo *"
file1 file2 file3
~$ bash -c "cd test ; echo !(file2)"  # expected output: file1 file3
bash: -c: line 0: syntax error near unexpected token `('
bash: -c: line 0: `cd test ; echo !(file2)'

He intentado todo tipo de escapar, pero nada de lo que he llegado con ha funcionado correctamente. También se sospecha extglob no está situado en una sub-shell, pero eso no es el caso:

~$ bash -c "shopt -s extglob ; cd test ; echo !(file2)"
bash: -c: line 0: syntax error near unexpected token `('
bash: -c: line 0: `cd test ; echo !(file2)'

Cualquier solución apreciada!

¿Fue útil?

Solución

$ bash -O extglob -c 'echo !(file2)'
file1 file3

Otros consejos

fiesta analiza cada línea antes de ejecutarlo, por lo que "extglob shopt -s" no va a haber entrado en vigor cuando se está validando fiesta de la sintaxis patrón de comodines. La opción no se puede activar en la misma línea. Es por eso que la solución "fiesta -O extglob -c 'xyz'" (de Randy Proctor) funciona y es necesario.

Aquí hay otra manera, si se quiere evitar eval y tiene que ser capaz de convertir extglob de encendido y apagado en el subnivel. Sólo hay que poner su patrón en una variable:

bash -c 'shopt -s extglob; cd test; patt="!(file2)"; echo $patt; shopt -u extglob; echo $patt'

da este resultado:

file1 file3
!(file2)

demostrando que extglob fue armar y desarmar. Si el primer echo tenía comillas alrededor de la $patt, sería simplemente escupir el patrón como el segundo echo (que probablemente debería tener comillas).

Bueno, no tengo ninguna experiencia ó real con extglob , pero puedo conseguir que funcione envolviendo la echo en un eval:

$ bash -c 'shopt -s extglob ; cd  test ; eval "echo !(file2)"'
file1 file3
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top