Como posso proteger os parênteses transmitidos para um comando cd? [duplicado]

18

Eu perguntei aqui como fazer cd proteger espaços. A conclusão da tabulação é ótima, mas às vezes você cola o caminho da área de transferência para que seja útil.

A solução quebra com parênteses no entanto. Não importa como você tenta escapar e proteger a entrada, ela sempre retorna:

bash: syntax error near unexpected token '('

Existe alguma maneira de lidar com parênteses? O que eu quero é que quando eu entrar, funcione:

cd My path with spaces (and parentheses)
    
por Strapakowsky 30.03.2013 / 02:35

2 respostas

17

Use aspas simples ' em torno do argumento. (Isso funciona para qualquer comando, não apenas cd ).

cd 'My path with spaces (and parentheses)'

Você não pode fazer o bash passar os parênteses para cd . Fazer os espaços funcionarem é um hack muito especializado.

As aspas simples funcionam em torno de cada caractere, exceto ' em si. Substitua aspas simples pela sequência de 4 caracteres '\'' .

cd 'Apostrophe'\''s a pain'

Isso não funciona se o nome do diretório começar com um hífen, porque isso faz com que o comando cd interprete o argumento como uma opção. Passe -- antes do nome do diretório para evitar isso.

Veja link para mais detalhes.

Outro método é fazer com que o shell leia uma linha separada de texto em vez de passar o argumento na linha de comando.

Strapakowsky@darkstar ~$ read -r; cd -- "$REPLY"
My path with spaces (and parentheses)
Strapakowsky@darkstar ~/My path with spaces (and parentheses)$ 

Em vez de copiar e colar manualmente, você pode fazer isso programaticamente. Instale o xclip ou o xsel .

cd -- "$(xclip -o -selection clipboard)"
cd -- "$(xsel -bo)"

Você pode tornar isso um alias.

alias cde='cd -- "$(xsel -bo)"'
    
por Gilles 30.03.2013 / 03:14
6

Como corretamente cd para diretórios com caracteres como espaços e parênteses em seus nomes:

Se o nome da sua pasta não incluir um caractere de aspas simples ' , coloque-o entre aspas simples:

cd 'My path with spaces (and parentheses)'

Se incluir um ' , mas não incluir um caractere de aspas duplas " , uma folga \ , um backquote ' ou um dólar $ , coloque-o entre aspas duplas:

cd "My path with spaces (and parentheses)"

Não é muito comum um nome de arquivo ou diretório conter aspas simples e duplas. (Isso talvez se deva ao fato de não ser comum o nome de um arquivo ou diretório conter aspas duplas. A única razão pela qual não recomendei as aspas duplas é que, diferentemente das aspas simples, as aspas duplas permitem que o $ expanda variáveis de ambiente. Isso seria um problema se o nome do arquivo contivesse um caractere $ seguido de texto.)

Se ele contiver ambos, ou se você quiser apenas outro método, então você pode escapar cada espaço e parênteses manualmente inserindo um caractere de barra invertida \ antes dele:

cd My\ path\ with\ spaces\ \(and parentheses\)

Isso é chato, mas, felizmente, o shell com faz isso para você , se você digitar o início do nome e pressionar a tecla Tab . Se houver mais de um nome de arquivo ou diretório que comece com My , talvez seja necessário digitar um pouco mais para expandi-lo. Se você pressionar Tab e ele não expandir, você pode pressionar Tab novamente para ver uma lista de arquivos que correspondem ao que você digitou até agora. Então você sabe quanto mais você deve digitar para que ele corresponda de maneira única e se expanda.

Como alternativa, você pode escapar das cotações internas. Por exemplo, suponha que você tenha uma pasta chamada:

Mischa's gardening tips for "home and office"

Você pode usar:

cd Mischa\'s\ gardening\ tips\ for\ \"home\ and\ office\"

Mas você também pode simplesmente usar:

cd 'Mischa'\''s gardening tips for "home and office"'

As barras invertidas não são especiais entre aspas simples, então terminamos a sequência entre aspas simples, acrescentamos uma aspa simples protegida por barra invertida e imediatamente iniciamos outra sequência com aspas simples, tudo sem nenhum espaço que inicie um argumento separado. / p>

Por que você provavelmente não pode fazer com que cd funcione da maneira que você queria:

Quanto a cd My path with spaces (and parentheses) funcionar: não, você realmente não pode fazer isso, porque esse comportamento não é específico para o comando cd , é parte da maneira como qualquer comando funciona. Quando um comando é executado, ele fornece uma lista de argumentos fornecidos pelo usuário. Quando o shell vê um espaço, ele sabe que um argumento acabou de terminar e outro acabou de começar. Para passar um espaço como parte de um argumento, ele deve ser citado de uma das formas acima.

Você poderia alcançar parte desse algum do tempo - você poderia fazer com que cd My path with spaces trabalhasse na pasta My path with spaces . Você poderia conseguir isso escrevendo um script de shell que concatene todos os seus argumentos fornecidos pelo usuário com espaços. (Então, se você quiser, pode fazer com que cd chame esse script, criando um alias de shell denominado cd para ele; isso terá precedência sobre o shell embutido cd que você está executando normalmente.) Mas:

  • O script não receberia argumentos diferentes para My path with spaces e My path with spaces , por isso cd My path with spaces falharia ou entraria na pasta errada.

  • Você não pode fazer isso para os parênteses, porque eles são usados para agrupar pelo shell, de forma que eles não sejam comunicados de forma alguma a um comando. Na verdade, na maioria das vezes, o shell simplesmente lança um erro de sintaxe (exatamente como você viu):

    ek@Kip:~$ cd My path with spaces (and parentheses)
    bash: syntax error near unexpected token '('
    

    Não importa o que você altere, esse erro de sintaxe continuará a ocorrer quando esse comando for fornecido.

Eu digo que você "provavelmente" não pode fazer este trabalho porque existe uma maneira que você pode - você pode fazer sua própria concha que se comporta como você deseja. Mas isso é extremamente difícil e é improvável que alguém queira fazer isso, apenas para fazer essa mudança. (Você também pode modificar o código-fonte de um shell existente, que é uma solução mais prática, mas ainda requer mais esforço do que a maioria das pessoas gostaria de exercer.) Além disso, é improvável que cd aceite nomes de diretório com caracteres arbitrários, incluindo espaços neles, como acontece no Windows.

Caso você esteja se perguntando por que isso funciona no Windows, mas não no Ubuntu: No Windows, os comandos são passados com o texto digitado depois deles como seqüência de texto e quando um comando precisa interpretar essa cadeia de caracteres como uma seqüência de argumentos separados (o que geralmente, mas nem sempre, faz), o código para o comando deve chamar uma função de biblioteca especial que analisa a seqüência de linha de comando. (Em um programa em C, isso acontece nos bastidores, mas ainda envolve o uso da API do Windows.)

    
por Eliah Kagan 30.03.2013 / 03:05