' es un ' error de directorio al intentar pasar el nombre del directorio a la función

En mi script bash, uso find para obtener los nombres de las carpetas mediante comodines:

for i in $(find ${directory} -mindepth 1 -type d -name ${wildcard}); do stuff=doStuff ${i} done doStuff() { echo ${1} return ${1}"/hello"; } 

El problema es que cuando hago esto, obtengo el siguiente error (digamos que $ {i} corresponden a «home / me / my_directory»):

line 111: "/home/me/my_directory": is a directory. 

(la línea 111 es la línea con «doStuff «)

He intentado hacer esto, sin éxito:

for i in $(find ${directory} -mindepth 1 -type d -name ${wildcard}); do stuff=doStuff "${i}" done 

Aparentemente es porque el programa está intentando ejecutar el directorio, pero solo lo quiero como una cadena que pueda manipular.

Comentarios

  • Hmmm …. Según la página de manual de bash. … El comando return incorporado en bash se usa para devolver un código EXIT (entero), no cualquier tipo de parámetro de cadena.
  • También puede probar find "${directory}" -mindepth 1 -type d -name "${wildcard}" -print0 | xargs -0 doStuff
  • googlers : otra excelente fuente para obtener este mensaje de error ge es //a wrong bash line comment en lugar de #a correct bash line comment

Respuesta

Las citas y la sustitución de comandos son sus problemas aquí.

El problema específico con el que se está encontrando es porque el shell está intentando ejecutar un comando llamado /home/me/my_directory con la variable de entorno stuff=doStuff.
Lo que realmente quieres (si» interpreto correctamente) es ejecutar doStuff con el valor de $i como argumento, asignando la salida a la variable stuff. La forma de hacer esto es envolver su comando en $(). Por ejemplo:

stuff="$(doStuff "$i")" 

Observe cómo también pongo comillas alrededor de todo. Esto es para evitar que el shell divida palabras que no quieres que divida (convertirá un solo argumento de /foo/bar baz en /foo/bar y baz).

Además, la salida de su función es lo que se usa como valor de retorno, no return.

Como debería usar más comillas, también debería agregarlas a todo lo demás. Aquí tienes una versión completa de tu script:

doStuff() { echo "${1}" >&2 printf "%s/hello" "$1"; } IFS=$"\n" for i in $(find "${directory}" -mindepth 1 -type d -name "${wildcard}"); do stuff="$(doStuff "${i}")" done 

Tienes que poner la definición de la función antes de intentar usarla. Shell no se analiza como los programas compilados, donde pasa por el archivo varias veces. Es de arriba hacia abajo.
También he modificado doStuff para enviar el echo a STDERR donde se mostrará en la terminal, y luego printf lo envía a STDOUT, donde se capturará en la variable stuff.

Tenga en cuenta que esto seguirá siendo un problema si alguno de sus directorios contiene una nueva línea. Sin embargo, esta es una limitación del shell. El único carácter que una ruta de archivo no puede contiene es un carácter NULL (\0). Sin embargo, bash y otros shells no pueden almacenar un carácter NULL en una cadena (no todos, pero muchos. Sé que zsh puede), así que puedes » No lo use como delimitador.

Comentarios

  • Solo quería agregar eso si tiene espacio antes / después =, se estropea. p.ej. MY_VAR = ' / some / path ' es válido pero MY_VAR = ' / some / La ruta ' o MY_VAR = ' / alguna / ruta ' no es

Respuesta

Ese es un buen esfuerzo, pero muestra que está intentando escribir bash como si fuera un lenguaje de programación, cuando en realidad es un lenguaje de scripting simple. El problema con su construcción stuff=doStuff arg es que para bash no significa lo que usted cree que significa. Para bash, stuff=doStuff es una asignación de variable y arg es un comando. Le sugiero que lea los siguientes dos enlaces:

Una versión funcional de algo similar a lo que tienes sería

doStuff () { echo "$1/hello" } stuff=$(doStuff "$i") 

Respuesta

La línea que da el error no hace lo que crees que hace:

Primero establece las cosas de la variable de entorno en la cadena «doStuff», y luego intenta ejecutar $ {i} como un comando. Y dado que $ {i} es un directorio, eso falla con el mensaje de error dado.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *