Digamos que eu quero armazenar o seguinte comando em uma variável
cd "/cygdrive/c/Program Files/"
Então eu faço isso
dir="cd \"/cygdrive/c/Program Files/\""
Isso deve armazenar o comando para navegar para o diretório Arquivos de Programa, portanto, quando eu digito $ dir, ele me leva para esse diretório. Para verificar se as cotações foram escapadas corretamente, digitei
echo $dir
o que me dá
cd "/cygdrive/c/Program Files/"
Então, tudo deve estar funcionando bem. No entanto, quando eu digito,
$dir
eu recebo
bash: cd: "/cygdrive/c/Program: No such file or directory
O que estou fazendo de errado? Estou usando o Cygwin, mas presumo que esse problema se aplique ao bash em geral.
Respostas:
Resposta curta: consulte BashFAQ # 050 ("Estou tentando colocar um comando em uma variável, mas os casos complexos sempre falham!").
Resposta longa: quando o bash analisa um comando, analisa aspas antes de substituir variáveis; ele nunca volta e analisa novamente as cotações nos valores das variáveis; portanto, elas acabam não fazendo nada útil. Usar echo para verificar o comando é completamente enganador, pois mostra o comando após ser analisado; se você quiser ver o que realmente está sendo executado, use
set -x
os comandos de impressão do shell conforme são executados ou use emprintf "%q " $dir; echo
vez de eco simples.Se você deseja armazenar um comando complexo (por exemplo, um com espaços ou outros caracteres especiais nas "palavras"), é necessário colocá-lo em uma matriz, em vez de uma variável de texto simples, e depois expandi-lo com o idioma `" $ { array [@]} ", assim:
Agora, se o objetivo é criar uma abreviação fácil de digitar, esse claramente não é o caminho a percorrer. Use um alias ou função de shell:
ou
fonte
Quando o bash se expande
$dir
, ele apenas executa a divisão de palavras e a globbing. Repartição de palavras produz três palavras:cd
,"/cygdrive/c/Program
eFiles/"
. Então o comando a executar écd
com dois argumentos;cd
apenas analisa seu primeiro argumento,,"/cygdrive/c/Program
que não é um diretório existente.Se você deseja executar uma avaliação completa do shell no conteúdo de uma variável, use
eval
:Observe que você precisa de aspas duplas
$dir
, caso contrário, a divisão de palavras seria realizada primeiro eeval
concatenaria seus argumentos com espaços. Isso funcionaria aqui, mas geralmente seria ruim (por exemplo, se houvesse dois espaços consecutivos em um nome de arquivo).No entanto, uma string não é o caminho certo para armazenar um comando shell que você deseja executar. A menos que você tenha um requisito incomum, você deve usar uma função:
Se você está realmente interessado em digitar
$dir
para mudar para um diretório específico e este não é apenas um exemplo simples, desde o bash 4, insirashopt -s autocd
seu.bashrc
e definaapós o qual você pode digitar apenas
"/cygdrive/c/Program Files/"
ou"$dir"
no prompt do shell para alternar para esse diretório. Você ainda precisa de aspas duplas$dir
; se você não gosta disso, use zsh em vez de bash.fonte
Armazenar comandos em variáveis geralmente não é uma boa ideia. É para isso que servem as funções e aliases.
Ao invés de
tente um destes:
ou
ou
O primeiro formulário, armazenando o nome do diretório em uma variável, significa um pouco mais de digitação, mas fica mais claro quando você executa o comando que está executando a
cd
. O segundo é o mais próximo do que você está tentando realizar. (Não uso muito pseudônimo no bash; não tenho certeza de que vantagem eles têm sobre as funções.)EDIT:
E
dir
provavelmente é um nome ruim para um apelido ou função, já que existe um comando existente com esse nome (é basicamente uma versão dols
, pelo menos se você tiver o GNU coreutils).fonte
Storing commands in variables is generally not a good idea. That's what functions and aliases are for.
Experimentar
Mas ainda mais especificamente:
/programming/4334467/cygwin-using-a-path-variable-containing-a-windows-path-with-a-space-in-it
fonte