Você pode declarar variable
como uma variável de ambiente, ou seja,
export variable="Filename:"
Em um script bash eu defino uma função que é chamada de find
. O problema é que o escopo das variáveis não se estende à função. Como eu acesso variáveis da função? Aqui está um exemplo:
variable="Filename:"
myfunction() {
echo $variable $1
}
export -f myfunction
find . -type f -exec bash -c 'myfunction "{}"' \;
Isso produzirá nomes de arquivos, mas sem a string "Filename:".
Existe, talvez, uma maneira melhor de chamar uma função de find
, de modo que ela seja chamada para todos os arquivos que find
encontra e as variáveis ainda estão definidas?
Não é uma resposta à sua pergunta, mas não faça :
find . -type f -exec bash -c 'myfunction "{}"' \;
Além do fato de que não é portátil, também é muito perigoso, porque os nomes dos arquivos acabam sendo interpretados por bash
como código shell. Considere, por exemplo, o que aconteceria se houvesse um arquivo chamado $(rm -rf ~)
lá embaixo. Escreva:
find . -type f -exec bash -c 'myfunction "$1"' find+bash {} \;
Ou melhor ainda (para evitar a execução de um bash
por arquivo):
find . -type f -exec bash -c 'for file do
myfunction "$file"; done' find+bash {} +
Agora, uma resposta à sua pergunta sobre o assunto:
Você pode fazer:
{ find . -type f -exec printf '%sfind . -type f -exec bash -c 'myfunction "{}"' \;
' {} + | while IFS= read -ru3 -d '' file; do
myfunction "$file"; done 3<&0 <&4 4<&-; } 4<&0
Dessa forma, você está chamando myfunction
dentro do shell bash
atual, portanto, não é necessário exportar myfunction
ou executar mais bash
shells.
Se o seu find
suportar o predicado -print0
(como GNU, busybox e alguns BSDs find
s), você poderá substituir -exec printf '%s
por %code% -print0
' {} +
Eu faria como segue
#!/bin/bash
myfunction() {
local var="Filename: "
local file=$1
echo "$var" "$file"
}
export -f myfunction
find . -type f -exec bash -c 'myfunction {}' \;
Declare vars como local e passe '{}' para a função que é $1
primeiro parâmetro posicional.
Quando você atribui a uma variável, ela começa como uma variável do shell. Para obter uma variável de ambiente que é passada para subprocessos, você precisa exportá-la.
variable="Filename:"
export variable
Você pode colocar a atribuição na mesma linha que export
: export variable="Filename:"
.
A variável será visível para os shells iniciados por find
, mas não para as funções. No bash, você também pode exportar funções. Esta possibilidade não está presente no ksh, no traço e em outros shells que são frequentemente usados como sh
porque são mais rápidos e mais finos.
export -f myfunction # bash only
Nunca use {}
dentro de uma string em find -exec …
(ou xargs …
), a menos que você saiba que seus nomes de arquivo são alfanuméricos. Se houver algum caractere especial nos nomes dos arquivos, eles serão analisados como tal pelo shell interno. Em vez disso, passe os nomes dos arquivos na linha de comando do shell.
find . -type f -exec bash -c 'for x; do myfunction "$x"; done' _ {} +
Com shells diferentes de bash, defina a função no shell interno ou apenas coloque seu código diretamente.
Como alternativa, no bash, você pode usar globalização recursiva em vez de localizar. Cuidado com o fato de que o bash atravessa links simbólicos para diretórios.
variable="Filename:"
myfunction () { … }
shopt -s globstar dotglob
for x in **/*; do
if [[ -f $x ]]; then myfunction "$x"; fi
done