Imagine que tenho duas pastas no meu diretório de trabalho atual: back/
e front/
. Estou tentando entrar em cada um deles e fazer algumas coisas. Do script simples abaixo:
for dir in */ ; do
echo "$(dir)"
done
Eu estava esperando uma saída como:
back
front
No entanto, o que estou recebendo é:
back front
back front
Eu não entendo. A consequência é que, se eu tentar cd
entrar na pasta:
for dir in */ ; do
echo "$(dir)"
cd $(dir)
echo "$(pwd)"
cd ..
done
Eu recebo:
back front
/path/to/back
back front
/path/to/back
Ou seja, eu nunca entro front/
. Alguém poderia me ajudar a entender o que estou fazendo de errado?
Muito obrigado,
Em shells do tipo POSIX,
$(cmd)
a sintaxe para substituição de comando é$(cmd)
expandida para a saída decmd
menos os caracteres de nova linha finais.O que você deseja é a expansão do parâmetro :
$dir
ou${dir}
(aqui com o parâmetro sendo adir
variável ).pwd
é o comando que gera o conteúdo da$PWD
variável especial que contém um caminho para o diretório de trabalho atual, portanto,$(pwd)
expande para a mesma coisa,$PWD
desde que$PWD
não termine em caracteres de nova linha.Então você quer:
Ou:
Lembre-se também disso
echo
não pode ser usado para gerar dados arbitrários, useprintf
em vez dissocd
significaria que o seguintecd ..
o levaria ao lugar errado se o primeirocd
falhasse.cd
em um subshell (usando(...)
) em vez de usarcd ..
, pois o último nem sempre garante que você retorne ao local inicial (se houver links simbólicos envolvidos e/ou alguns componentes do caminho tiverem sido renomeados no intervalo)--
deve ser usado para separar opções de não opções quando não é possível garantir que as não opções não comecem-
(ou+
o que também pode ser um problema para alguns comandos).Lembre-se também de que no bash (e em outros shells POSIX, exceto zsh), quando um glob não corresponde a nenhum arquivo, ele não é expandido.
Portanto, se o diretório de trabalho atual não contiver nenhum arquivo não oculto que possa ser determinado como sendo do tipo directory , o
*/
padrão glob apenas se expandirá para si mesmo*/
em vez de uma lista vazia e você provavelmente verá um erro aocd
fazer isso. não entre nesse*/
diretório.Em
zsh
, você usaria oN
qualificador glob como emfor dir in */(N); do...
(oufor dir in *(N-/); do...
para evitar$dir
terminar em/
).Em ksh93:
for dir in ~(N)*/; do...
.Em
bash
, você pode definir anullglob
opção globalmente temporariamente:Para completar,
$(var)
é a sintaxe para expansões de macroMakefile
em s conforme usada pelomake
comando.Na
awk
linguagem,$
é um operador unário para desreferenciar campos, e você usa apenasvar
para se referir a umaawk
variável. Então,$(var)
seria o mesmo que$var
ou$ var
e expandiria para ovar
campo (ou todo o registro sevar
for 0).Em
rc
shells semelhantes a -,$(var)
o mesmo que$var
,$ var
,$ 'var'
,$ ( 'var' )
também funcionaria, já que é uma lista de um elemento passado para$
, então você está desreferenciando avar
variável, embora normalmente usaria apenas$var
.No TCL,
$(var)
expandiria para o valor da variável array com nome vazio para avar
chave: