' é um erro de diretório ' ao tentar passar o nome do diretório para a função

No meu script bash, uso find para obter os nomes das pastas por curinga:

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

O problema é que, quando faço isso, recebo o seguinte erro (digamos que $ {i} corresponda a “home / me / my_directory”):

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

(linha 111 é a linha com “doStuff “)

Eu tentei fazer isso, sem sucesso:

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

Aparentemente, é porque o programa está tentando executar o diretório, mas eu quero apenas como uma string que eu possa manipular.

Comentários

  • Hmmm …. De acordo com a página de manual do bash. … O comando interno de retorno em bash é usado para retornar um código EXIT (inteiro) e não qualquer tipo de parâmetro de string.
  • Você também pode tentar find "${directory}" -mindepth 1 -type d -name "${wildcard}" -print0 | xargs -0 doStuff
  • googlers : outra ótima fonte para obter esta mensagem de erro ge é //a wrong bash line comment em vez de #a correct bash line comment

Resposta

Citações e substituição de comandos são seus problemas aqui.

O problema específico que você está enfrentando é porque o shell está tentando executar um comando chamado /home/me/my_directory com a variável de ambiente stuff=doStuff.
O que você realmente deseja (se eu estiver interpretando corretamente) é executar doStuff com o valor de $i como um argumento, atribuindo a saída à variável stuff. A maneira de fazer isso é envolver seu comando em $(). Por exemplo:

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

Observe como também coloco aspas em tudo. Isso evita que o shell divida coisas que você não deseja (ele transforma um único argumento de /foo/bar baz em /foo/bar e baz).

Além disso, a saída de sua função é o que é usado como o valor de retorno, não return.

Como você deve usar mais aspas, também deve adicioná-las a todo o resto. Aqui está uma versão completa do seu 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 

Você deve colocar a definição da função antes de tentar usá-la. O shell não é analisado como programas compilados, onde percorre o arquivo várias vezes. É de cima para baixo.
Eu também modifiquei doStuff para enviar o echo para STDERR onde será mostrado no terminal e, em seguida, printf envia para STDOUT, onde será capturado na variável stuff.

Observe que isso ainda terá um problema se algum de seus diretórios contiver uma nova linha. No entanto, esta é uma limitação do shell. O único caractere que um caminho de arquivo não pode conter é um caractere NULL (\0). No entanto, bash e outros shells não podem armazenar um caractere NULL em uma string (nem todos, mas muitos. Eu sei que zsh pode), então você pode ” use-o como um delimitador.

Comentários

  • Só queria adicionar isso se você tiver espaço antes / depois =, ele bagunça. por exemplo. MY_VAR = ' / some / path ' é válido, mas MY_VAR = ' / some / caminho ' ou MY_VAR = ' / some / path ' não é

Resposta

É um bom esforço, mas mostra que você está tentando escrever bash como se fosse uma linguagem de programação, quando na verdade é uma linguagem de script simples. O problema com sua construção stuff=doStuff arg é que para bash isso não significa o que você pensa que significa. Para bash, stuff=doStuff é uma atribuição de variável e arg é um comando. Sugiro que você leia os dois links a seguir:

Uma versão funcional de algo semelhante ao que você tem seria

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

Resposta

A linha que apresenta o erro não faz o que você pensa:

Primeiro, ele define a variável de ambiente stuff para a string “doStuff” e, em seguida, tenta executar $ {i} como um comando. E como $ {i} é um diretório, isso falha com a mensagem de erro fornecida.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *