Comment échapper au «(accent grave / backtick) dans un chemin?

13

J'ai tendance à préfixer les fichiers et dossiers souvent utilisés avec le caractère "accent grave" (tilde non-shift, le back-tick, ou l'accent simple, whathaveyou ..), car il est facile à atteindre, et laissez-moi trier les choses par ordre alphabétique, tout en me laissant choisir d'afficher quelques éléments en haut. Cela fonctionne bien, sauf lorsque je vais accéder à ces fichiers via la CLI ou SSH / SCP.

Si j'essaie d'exécuter une commande, en appelant le fichier sans échapper ↝ cela me lance dans une session interactive .. par exemple ↯

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

Pourtant, si j'essaie la solution logique ↯

# 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

Je sais que la "nouvelle" règle consiste à utiliser une syntaxe comme export NOW=$(date)vs export NOW= `date` (en fait, j'ai eu du mal à écrire cette dernière dans la syntaxe SE MD ...) mais cela n'a aucun rapport avec le ENVou n'importe quel script. ..

Remarque: il s'agit d' un environnement Mac OS X, mais cela dit, l'interface graphique n'a jamais eu de problème pour gérer ce personnage au quotidien, et généralement, s'il y a un problème de syntaxe dans le terminal, Apple fait un très bon travail de désactivation du comportement dans l'interface graphique ... Je ne sais pas si c'est un bogue, ou si la technique pour traiter de tels chemins est simplement obscure .. mais jusqu'à présent, je n'ai pas pu trouver un façon "d'y échapper" ?

mralexgray
la source
pourquoi ne pas simplement utiliser un caractère qui n'a pas besoin de s'échapper comme le chiffre 1?
JamesRyan
le backtick est - visuellement - moins perturbateur (pour moi), et a un bagage sémantique moins inhérent lorsqu'il est re-proposé comme un délimiteur de tri.
mralexgray

Réponses:

10

Vous pouvez utiliser 3 barres obliques inverses comme mentionné par Jed Daniels ou vous pouvez l'encapsuler entre guillemets simples (')et utiliser une seule barre oblique inverse.

Des exemples des deux sont ci-dessous.

$ 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     
$
Rik Schneider
la source
impressionnant. Je suppose que je vais choisir cette réponse parce que c'est agréable d'avoir deux façons de le faire. dans les deux cas, vous pouvez également utiliser cette technique localement, en utilisant une seule barre oblique, ou pour le slash-averse, NO SLASHES et simplement la technique de guillemet simple autour du fichier ou du répertoire problématique .. merci!
mralexgray
5

Trois barres obliques inverses devraient le faire:

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

La première barre oblique inversée échappe au backtick afin qu'il soit envoyé de l'autre côté, mais l'autre côté renvoie l'erreur car il s'attend à ce que les backticks soient par paires. La deuxième barre oblique inverse échappe à la première barre oblique inverse, puis vous avez besoin des deux barres obliques inversées supplémentaires pour pouvoir envoyer une barre oblique inversée de l'autre côté.

EDIT: Comme le mentionne Rik, vous pouvez également le faire avec un seul devis. Je n'y avais pas pensé parce que vous ne pouvez pas le faire avec des variables (elles ne seront pas développées sur le système local lors des guillemets simples).

Jed Daniels
la source
3

Normalement, les lignes de commande sont interprétées une fois par le shell. Cependant, pour des raisons historiques, scp transmet également le nom du fichier au shell distant, de sorte que le nom du fichier est interprété deux fois par des shells . C'est aussi ce qui fait que les choses scp remote:'/path/prefix*' /path/local/fonctionnent, le shell distant se développe /path/prefix*.

Le moyen le plus simple d'éviter la deuxième extension est d'utiliser sftp, qui n'utilise pas de shell distant. Il fait toujours de l'expansion glob, mais comme vous pouvez lui donner des commandes sur stdin, vous pouvez éviter complètement votre expansion shell locale.

En dehors de cela, vous pouvez utiliser n'importe quel mécanisme de citation normal du shell, y compris ceux fournis par @Jed Daniels et @Rik Schneider, mais je voulais expliquer ce qui se passe réellement et mentionner sftp.

(Vous pouvez utiliser toutes sortes de fonctionnalités du shell dans votre nom de fichier scp, par exemple scp server:\$HOME/file dest, utilisera l' idée du shell distant$HOME , alors que si vous supprimiez le \, il utiliserait votre shell local .).

derobert
la source