Estou tentando cd
aceitar um nome de diretório redirecionado para ele a partir de outro comando. Nenhum desses métodos funciona:
$ echo $HOME | cd
$ echo $HOME | xargs cd
Isso funciona:
$ cd $(echo $HOME)
Por que o primeiro conjunto de comandos não funciona e existem outros que também falham dessa maneira?
shell
io-redirection
pipe
cd-command
Jhonathan
fonte
fonte
Respostas:
cd
não é um comando externo - é uma função interna do shell. Ele é executado no contexto do shell atual e não, como comandos externos, em um contexto fork / exec'd como um processo separado.Seu terceiro exemplo funciona, porque o shell expande a variável e a substituição do comando antes de chamar o
cd
builtin, para quecd
receba o valor${HOME}
como argumento.Sistemas POSIX fazer ter um binário
cd
- na minha máquina FreeBSD, é a/usr/bin/cd
, mas não faz o que você pensa. Chamar o bináriocd
faz com que o shell bifurque / execute o binário, o que de fato altera seu diretório de trabalho para o nome que você passa. No entanto, assim que o faz, o binário sai e o processo bifurcado / exec desaparece, retornando você ao seu shell, que ainda está no diretório em que estava antes de iniciar.fonte
cd
comando externo ?cd
não lê a entrada padrão. É por isso que seu primeiro exemplo não funciona.xargs
precisa de um nome de comando, ou seja, um nome de um executável independente.cd
precisa ser um comando interno do shell e não teria efeito (além de verificar se você pode mudar para esse diretório e os possíveis efeitos colaterais que ele pode ter para diretórios de montagem automática) se fosse um executável. É por isso que o seu segundo exemplo não funciona.fonte
Além da boa resposta existente, também vale a pena mencionar que um pipe bifurca um novo processo, que possui seu próprio diretório de trabalho separado. Portanto, tentar fazer isso não funcionará:
Portanto, você não estará na pasta / depois que o shell retornar deste comando.
fonte
a | b
, mesmo sea
eb
está embutido, pelo menos um não, então não executar no processo shell, mas não há garantia de que qual deles é. Por exemplo, na AT&Tksh
,zsh
oubash -O lastpipe
,b
é executado no processo atual do shell, portanto, seu código o levaria para / lá.Além das respostas corretas já fornecidas: Se você executa o bash e deseja descobrir o que é um "comando" como o cd, pode usar o tipo
ou porque não:
enquanto, por exemplo, o tempo gnu normalmente já está incluído na sua distribuição favorita:
Okey okey, você entendeu a ideia, então que diabos é esse tipo?
Aqui está um snippet manual do bash:
fonte
Como já foi dito, ele não funcionará porque
cd
é um comando interno do shell, não um programa externo; portanto, não possui nenhuma entrada padrão na qual você possa inserir algo.Mas, mesmo que funcionasse, não faria o que você deseja: um canal gera um novo processo e redireciona a saída padrão do primeiro comando para a entrada padrão do segundo, portanto, apenas o novo processo alterará seu funcionamento atual diretório; isso não poderia afetar o primeiro processo de forma alguma.
fonte
read
geralmente é (sempre?) um shell embutido. É verdade quecd
ignora stdin, mas isso não se deve ao fato de ser um builtin.Outra opção são backticks, que colocam o stdout de um comando como argumento da linha de comando de um segundo comando e são mais portáteis que
$(...)
. Por exemplo:ou mais geralmente;
Observe que o uso de backticks depende do shell para executar o comando e substituir a saída na linha de comando. A maioria das conchas suporta isso.
fonte
$(...)
funciona. Eu não acho que seja um bom conselho recomendar backticks, pois eles têm regras de cotação muito mais complicadas e geralmente são mais propensas a erros. (Veja §3.5.4 "Substituição de comando" no Manual de referência do Bash .)$(...)
em um sistema, mas não em outro?$(…)
. Os sistemas sem um shell POSIX (ou seja, com um shell Bourne genuíno) seriam extremamente antigos. Mesmo sistemas onde/bin/sh
existe um shell Bourne e você precisa de outro caminho, como/usr/xpg4/bin/sh
um shell POSIX, são raros hoje em dia. A recomendação de backticks para quem não administra profissionalmente o antigo unix boxen está fazendo um desserviço.