Estoy intentando crear un script BASH que lea argumentos, probando si son archivos de directorio, ordinarios, ejecutables o de enlace simbólico e imprimirlos en la terminal.
Al ejecutar mi script, uso "./myscript.bash *" para ver, pero no obtengo ningún resultado previsto. Recibo que los nombres de todos los elementos en mi directorio de inicio son "no encontrados" únicamente. Ejemplo:
"Escritorio no encontrado", "Descargas no encontradas", etc. AUNQUE estén allí, en mi carpeta de inicio, y sean directorios. ¿Alguien sabe qué estoy haciendo mal?
#!/bin/bash
for i in $*; do
if [ -d “{$i}” ]; then
echo “${i} (Directory)”;
elif [ -x “{$i}” ]; then
echo “${i} (Executable)”;
elif [ -h “{$i}” ]; then
echo “${i} (Symbolic)”;
elif [ -f “{$i}” ]; then
echo “${i} (Ordinary)”;
else
echo “${i} not found”
fi
done
Respuesta1
Primera regla para depurar scripts simples:
Si no funciona, intenta hacer eco.
En este caso:
for i in $*; do
echo "testing if “{$i}” exists"
if [ -d “{$i}” ]; then
echo “${i} (Directory)”;
<... rest of the script ...>
Inmediatamente verás que la respuesta es:
testing if “{Downloads}” exists
...
Es decir: la prueba es si existe “{Descargas}” (smartquotes-accolade open-Downloads-accolade close smartquotes).
Probablemente ese directorio no exista.
Las comillas inteligentes pueden ser un descuido para un scripter principiante. Bash (y también la mayoría de los otros shells) son muy exigentes en el uso de comillas. Una comilla simple ( '
) tiene un significado diferente al de una comilla doble ( "
). Las comillas inversas también significan algo diferente. Las citas inteligentes son las que te dio mamá, no hagas nada en absoluto (si perdonas mi referencia a Jefferson Airplane). Definitivamente querrás usar comillas dobles ( "
) aquí, porque permiten la expansión variable.
Los siguientes son los {
y }
. En el tuyo echo
, das:
echo “${i} not found”
pero en el if
lo es {$i}
. Encuentra la diferencia. si usaste
if [ -d "${i}" ]; then
hubiera funcionado.
Kamil escribió en sus comentarios:
Casi nunca lo deseas
$*
; casi siempre quieres"$@"
en su lugar.
y tiene razón. Hay páginas completas dedicadas a la diferencia de $*
y "$@"
, pero la forma más sencilla de mostrar la diferencia es con:
#!/bin/bash
echo ------------------
echo '$*'
for i in $* ; do echo $i ; done
echo ------------------
echo '"$@"'
for i in "$@" ; do echo $i ; done
echo ------------------
(Llamé a este script a
) y lo ejecuto con:
bash a 'plop 123' plop 123
------------------
$*
plop
123
plop
123
------------------
"$@"
plop 123
plop
123
------------------
Respuesta2
@ljm dio en el clavo, lo único que diría para ampliar eso es siempre hacer eco del resultado deseado y crear una mejor funcionalidad en torno a eso.
En resumen, primero asegúrese de que funcione y luego haga que funcione mejor.