web-dev-qa-db-fra.com

Comment puis-je protéger les parenthèses passées à une commande cd?

J'ai demandé ici comment rendre cd protéger les espaces. La complétion par tabulation est excellente, mais parfois vous collez le chemin à partir du Presse-papiers, ce qui est utile.

La solution rompt cependant entre parenthèses. Peu importe comment vous essayez d'échapper et de protéger l'entrée, elle retourne toujours:

bash: syntax error near unexpected token `('

Y a-t-il un moyen de le traiter également avec des parenthèses? Ce que je veux, c’est que lorsque j’écris ceci, cela fonctionne:

cd My path with spaces (and parentheses)
21
Strapakowsky

Utilisez des guillemets simples ' autour de l'argument. (Cela fonctionne pour n’importe quelle commande, pas seulement cdname__).

cd 'My path with spaces (and parentheses)'

Vous ne pouvez pas faire passer par bash les parenthèses à cdname__. Obtenir des espaces de travail est un hack très spécialisé.

Les guillemets simples contournent tous les caractères, à l'exception de '. Remplacez les guillemets simples par la séquence de 4 caractères '\''.

cd 'Apostrophe'\''s a pain'

Cela ne fonctionne pas si le nom du répertoire commence par un tiret, car la commande cdinterprète l'argument comme une option. Passez -- avant le nom du répertoire pour éviter cela.

Voir https://unix.stackexchange.com/questions/69144/how-do-i-escape-a-sub-directory-name-with-an-ampersand-in-it/69147#69147 = pour plus de détails.

Une autre méthode consiste à demander au shell de lire une ligne de texte séparée au lieu de transmettre l’argument sur la ligne de commande.

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

Plutôt que de copier-coller manuellement, vous pourriez aussi bien le faire par programme. Installez soit xclip ou xsel .

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

Vous pourriez en faire un alias.

alias cde='cd -- "$(xsel -bo)"'
23
Gilles

Comment correctement cd vers des répertoires contenant des caractères tels que des espaces et des parenthèses dans leurs noms:

Si votre nom de dossier n'inclut pas un caractère guillemet simple ', placez-le simplement entre guillemets simples:

cd 'My path with spaces (and parentheses)'

S'il contient un ', mais n'inclut pas un caractère guillemet double ", un slash \, un backquote ` ou un dollar $, mettez-le entre guillemets:

cd "My path with spaces (and parentheses)"

Il n'est pas très courant qu'un nom de fichier ou de répertoire contienne des guillemets simples et doubles. (Ceci est peut-être dû au fait qu'il n'est pas courant qu'un nom de fichier ou de répertoire contienne des guillemets. La seule raison pour laquelle je n'ai pas recommandé les guillemets à l'origine est que, contrairement aux guillemets simples, les guillemets permettent au $ de développer les variables d'environnement. Cela poserait un problème si votre nom de fichier contenait un caractère $ suivi d'un texte.)

Si elle contient les deux, ou si vous voulez simplement une autre méthode, vous pouvez alors échapper manuellement chaque espace et parenthèse en insérant un caractère barre oblique inverse \ devant celle-ci:

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

C'est ennuyeux, mais heureusement, le shell avec faites-le pour vous, si vous tapez le début du nom et appuyez sur Tab. S'il existe plus d'un nom de fichier ou de répertoire qui commence par My, vous devrez peut-être en saisir un nombre supplémentaire pour le développer. Si vous appuyez sur Tab et il ne s'étend pas, vous pouvez appuyer sur Tab à nouveau pour voir une liste de fichiers qui correspondent à ce que vous avez tapé jusqu'à présent. Ensuite, vous savez combien vous devez taper de plus pour obtenir une correspondance unique et une extension.

Vous pouvez également échapper aux guillemets internes. Par exemple, supposons que vous ayez un dossier appelé:

Mischa's gardening tips for "home and office"

Vous pouvez utiliser:

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

Mais vous pouvez aussi simplement utiliser:

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

Les barres obliques inverses ne sont pas spéciales entre guillemets simples. Nous terminons donc la chaîne entre guillemets simples, ajoutons un guillemet simple protégé par des barres obliques inverses et commençons immédiatement une autre chaîne entre guillemets simples, le tout sans aucun espace permettant de démarrer un argument séparé.

Pourquoi vous ne pouvez probablement pas faire fonctionner cd comme vous le souhaitiez:

Pour ce qui est de faire fonctionner cd My path with spaces (and parentheses): non, vous ne pouvez vraiment pas le faire, car ce comportement n'est pas spécifique à la commande cd, il fait partie du fonctionnement de n'importe quelle commande. Lorsqu'une commande est exécutée, elle fournit une liste d'arguments fournis par l'utilisateur. Lorsque le shell voit un espace, il sait qu'un argument vient de se terminer et qu'un autre ne fait que commencer. Pour passer un espace dans le cadre d'un argument, vous devez le citer de l'une des manières ci-dessus.

Vous pourriez obtenir ne partie de ceci certains du temps - vous pourriez faire en sorte que cd My path with spaces fonctionne dans le dossier My path with spaces. Vous pouvez y parvenir en écrivant un script shell qui concatène tous les arguments fournis par l'utilisateur avec des espaces. (Ensuite, si vous le souhaitez, vous pouvez appeler cd lui-même ce script en créant un alias de shell nommé cd; cette option aura préséance sur celle du shell cd que vous êtes actuellement. en cours d'exécution.) Mais:

  • Le script ne recevrait pas différents arguments pour My path with spaces et My path with spaces, de sorte que cd My path with spaces échouera ou entrera dans le mauvais dossier.

  • Vous ne pouvez pas le faire pour les parenthèses, car celles-ci sont utilisées pour le regroupement par le shell, de sorte qu'elles ne sont en aucun cas communiquées à une commande. En fait, la plupart du temps, le shell émettra simplement une erreur de syntaxe (comme vous l'avez vu):

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

    Quoi que vous changiez, cette erreur de syntaxe continuera de se produire lorsque cette commande est donnée.

Je dis que vous "probablement" ne pouvez pas faire cela parce qu'il y a un moyen de le faire: vous pouvez créer votre propre Shell qui se comporte comme vous le souhaitez. Mais cela est extrêmement difficile et il est peu probable que quelqu'un veuille le faire, simplement pour apporter ce changement. (Vous pouvez également modifier le code source d'un shell existant, ce qui est une solution plus pratique, mais qui nécessite encore plus d'efforts que la plupart des gens ne voudraient en faire.) De plus, il est peu probable que cd puisse accepter des noms de répertoire avec caractères incluant des espaces, comme sur Windows.

Dans le cas où vous vous demandez pourquoi cela fonctionne sous Windows mais pas sous Ubuntu: sous Windows, les commandes sont passées au texte tapé après eux sous la forme chaîne de texte, et lorsqu'une commande doit interpréter cette chaîne comme suit: une séquence d’arguments séparés (ce qu’elle fait habituellement, mais pas toujours), le code de la commande doit appeler une fonction de bibliothèque spéciale qui analyse la chaîne de ligne de commande. (Dans un programme C, cela se produit dans les coulisses, mais implique toujours l'utilisation de l'API Windows.)

6
Eliah Kagan