Estou vendo um comportamento "xargs" que parece ser bastante inesperado, na minha experiência. Eu uso "ls" para encontrar um nome de pasta correspondente e enviá-lo para "cd" usando "xargs". Recebo a mensagem de que a pasta não existe. Se eu não usar "xargs", no entanto, o "cd" funcionará. Além disso, se eu usar "xargs", mas enviar para "ls" em vez de "cd", também funcionará.
# Identify desired directory
ls -d *[Aa]nt*
201909+ants/
# Print the desired command with "echo"
ls -d *[Aa]nt* | xargs echo cd
cd 201909+ants/
# Execute the desired command and get error
ls -d *[Aa]nt* | xargs cd
xargs: cd: No such file or directory
# Confirm that the desired command without "xargs"
cd 201909+ants # This works no problem
cd .. # Go back up
cd 201909+ants/ # This works no problem
cd .. # Go back up
# Confirm that "xargs" with "ls"
ls -d *[Aa]nt* | xargs ls -d
201909+ants/
Estou convencido de que este é um problema ID1OT entre o teclado e a cadeira. Alguém pode apontar onde está o meu erro?
Estou usando o Bash do Cygwin, mas raramente vejo uma disparidade com o Linux. Não me lembro da última vez que vi tal disparidade.
O diretório de trabalho é uma propriedade do processo em execução e as alterações nele devem ser feitas dentro do próprio processo. Portanto,
cd
é um comando embutido no shell. Masxargs
não é (bem, geralmente), e não pode executar embutidos do shell. O que ele faz é chamar um programa externo.Como
cd
realmente não funciona como um programa externo, geralmente não está disponível como tal em sistemas Linux. É por isso que você recebe o erro.Em outros sistemas pode ser, porque algumas especificações dizem que tem que ser. Veja Por que o cd não é um programa? . Porém, não é muito útil, apenas altera o diretório de trabalho do
cd
processo, que sai imediatamente.Mas, você não precisa
ls
aqui, ouxargs
. Se você fizer issols *.txt
ou algo assim, é o shell que cria uma lista dos nomes de arquivos que correspondem ao padrão, essa lista é passada parals
, que... apenas os imprime. Praticamente o mesmo que se você fizesseecho *.txt
. (ls -l *.txt
faria mais sentido, já que lá,ls
faz algum trabalho real em encontrar todos os outros dados sobre os arquivos.) Então, em vez dels *[Aa]nt* |xargs
, você poderia (aproximadamente) usarecho *[Aa]nt* | xargs
e isso também é redundante, jáecho
que imprime sua linha de comando exargs
a transforma em entrada em uma linha de comando para outro programa.Nos casos simples, você deve ser capaz de simplesmente ir com
Mas se o padrão corresponder a mais de um nome de arquivo, você receberá um erro (ou comportamento estranho em alguns shells, por exemplo, em ksh
cd foo bar
faz uma substituição de string no caminho do diretório de trabalho atual.)(é claro que
ls *.txt
imprime os nomes dos arquivos um por linha quando redirecionado para um pipe, masecho *.txt
imprime todos eles em uma linha para que não sejam exatamente os mesmos.)