Como escapar de um '' (sotaque grave / backtick) em um caminho?

10

Eu prefiro prefixar arquivos e pastas usados com o caractere "sotaque grave" (não-shift til, o retro-carrapato ou o sotaque simples, whathaveyou ..), como é fácil chegar, e vamos classificar as coisas em ordem alfabética, enquanto deixo que eu escolha mostrar alguns itens no topo. funciona bem, exceto quando eu vou acessar esses arquivos via CLI ou SSH / SCP.

Se eu tentar executar um comando, chamando o arquivo sem escape ↝ ele me chuta para uma sessão interativa .. por exemplo ↯

# scp -r dns.local:/'Downloads/CrazyRussianCars/ ~/
↩
>

No entanto, se eu tentar a solução lógica ↯

# scp -r dns.local:/\'Downloads/CrazyRussianCars/ ~/
↩
bash: -c: line 0: unexpected EOF while looking for matching '''
bash: -c: line 1: syntax error: unexpected end of file

Eu sei que a regra "nova" é usar uma sintaxe como export NOW=$(date) vs export NOW= 'date' (na verdade, eu tive um tempo de sobra mesmo escrevendo o último na sintaxe do SE MD ...) mas isso não está relacionado ao ENV ou qualquer script ...

Nota: Este é um ambiente Mac OS X, mas dito isto, a GUI nunca teve problemas em lidar com este personagem no dia-a-dia e, normalmente, se houver um problema de sintaxe no Terminal, a Apple faz um bom trabalho ao desativar o comportamento na GUI ... Não tenho certeza se isso é um bug, ou se a técnica para lidar com esses caminhos é simplesmente obscuro .. mas até agora, eu fui incapaz de encontrar uma maneira de "escapar" ?

    
por mralexgray 01.07.2011 / 18:37

3 respostas

8

Você pode usar 3 barras invertidas, como mencionado por Jed Daniels, ou pode agrupá-las entre aspas simples (') e usar uma única barra invertida.

Exemplo de ambos estão abaixo.

$ touch dir/''rik' 
$ ls -l dir
total 1865376
-rw-r--r--  1 rik  staff          0 Jul  1 09:51 'rik 
$ scp localhost:dir/\\'rik ./ 'rik         
100%    0     0.0KB/s   00:00     
$ scp localhost:dir/'\'rik' ./ 'rik     
100%    0     0.0KB/s   00:00     
$
    
por 01.07.2011 / 18:59
5

Três barras invertidas devem fazer isso:

jed@jed-osx:~$ ls -la \'foo
ls: 'foo: No such file or directory
jed@jed-osx:~$ scp desk:\\'foo .
'foo                                            100%    0     0.0KB/s   00:00    
jed@jed-osx:~$ ls -la \'foo
-rw-r--r--  1 jed  staff  0 Jul  1 09:45 'foo
jed@jed-osx:~$ rm \'foo

A primeira barra invertida escapa do backtick para ser enviada para o outro lado, mas o outro lado lança o erro porque espera que os backticks estejam em pares. A segunda barra invertida escapa da primeira barra invertida, então você precisa das duas barras invertidas extras para poder enviar uma barra invertida de escape para o outro lado.

EDIT: Como o Rik menciona, você também pode fazer isso com uma única citação. Eu não tinha pensado nisso porque você não pode nos usar com variáveis (elas não serão expandidas no sistema local quando estiverem entre aspas simples).

    
por 01.07.2011 / 18:42
3

Normalmente, as linhas de comando são interpretadas pelo shell uma vez. No entanto, por razões históricas, scp passa o nome do arquivo para o shell remoto também, então o nome do arquivo é interpretado por shells duas vezes . Isso também faz com que coisas como scp remote:'/path/prefix*' /path/local/ work, o shell remoto esteja expandindo /path/prefix* .

A maneira mais fácil de evitar a segunda expansão é usar o sftp, que não usa um shell remoto. Ainda faz expansão glob, mas desde que você pode dar comandos em stdin, você pode evitar a expansão de shell local inteiramente.

Além disso, você pode usar qualquer um dos mecanismos normais de citação de shell, incluindo os fornecidos por @Jed Daniels e @Rik Schneider, mas eu queria explicar o que realmente está acontecendo e mencionar o sftp.

(Você pode usar todos os tipos de recursos do shell em seu nome de arquivo scp, por exemplo, scp server:\$HOME/file dest usará a ideia do shell remoto de $HOME , ao passo que você tirou o \ , ele usaria seu shell local .

    
por 01.07.2011 / 22:17