Script bash vers cd vers répertoire avec des espaces dans le chemin

94

J'utilise Bash sur macOS X et j'aimerais créer un simple fichier de script exécutable qui changerait vers un autre répertoire lorsqu'il est exécuté. Cependant, le chemin d'accès à ce répertoire contient des espaces. Comment diable faites-vous cela? C'est ce que j'ai ...

Nom du fichier: cdcode

Contenu du fichier:

cd ~/My Code

Maintenant accordé, ce n'est pas un chemin long, mais mon chemin réel est de cinq répertoires de profondeur et quatre de ces répertoires ont des espaces dans le chemin.

BTW, je l' ai essayé cd "~/My Code"et cd "~/My\ Code"ni de ces travaillé.

Benjamin W.
la source
1
J'ai un problème similaire à celui décrit. C'est-à-dire qu'aucun des moyens possibles pour passer à un répertoire contenant un espace. Rien de tel que: cd "My Passport" cd My \ Passport cd My "Passport" rien ne fonctionne. La complition fonctionne bien. Je peux lister: ls -l My \ Passport / fonctionne très bien. \> uname -a hôte Linux 2.6.18-8.1.8.el5.centos.plus # 1 SMP Mon Jul 16 08:49:50 EDT 2007 i686 i686 i386 GNU / Linux \> bash --help GNU bash, version 3.1 .17 (1) -release- (i686-redhat-linux-gnu) des idées s'il vous plaît?
Denis C

Réponses:

81

Lorsque vous double-citez un chemin, vous arrêtez l'expansion du tilde. Il y a donc plusieurs façons de procéder:

cd ~/"My Code"
cd ~/'My Code'

Le tilde n'est pas cité ici, donc l'expansion du tilde sera toujours exécutée.

cd "$HOME/My Code"

Vous pouvez développer les variables d'environnement dans des chaînes entre guillemets; c'est essentiellement ce que fait l'expansion du tilde

cd ~/My\ Code

Vous pouvez également échapper les caractères spéciaux (tels que l'espace) avec une barre oblique inverse.

derobert
la source
3
Vous pouvez même cd ~ / My '' Code, mais ce serait idiot quand vous pouvez y échapper avec une barre oblique inverse à la place
Nick Dixon
41

J'ai trouvé la solution ci-dessous sur cette page :

x="test\ me"  
eval cd $x

Une combinaison de \dans une constante de texte entre guillemets et un evalavant cdfait fonctionner comme un charme!

user365757
la source
plus de clarté: Pour un cd dans le répertoire d'un fichier d'un script: DIR = $ (dirname "$ 0"); eval cd $ DIR
Michael Scott Cuthbert
1
Cela m'a vraiment aidé à exécuter un script bash sur une machine OS X. 🎉
timbillstrom
Il n'y a vraiment pas besoin evalici.
Benjamin W.
2
Sous OS X, je ne pourrais pas faire fonctionner les autres / précédentes réponses sans eval.
D. Woods
10
cd ~/My\ Code

semble fonctionner pour moi ... Si laisser tomber les guillemets mais garder la barre oblique ne fonctionne pas, pouvez-vous publier un exemple de code?

Andrew Flanagan
la source
10

Vous pouvez utiliser l'un des éléments suivants:

cd ~/"My Code"
cd ~/M"y Code"
cd ~/My" Code"

Vous ne pouvez pas utiliser:

cd ~"/My Code"

Le premier fonctionne parce que le shell développe ~ / en $ HOME /, puis clique sur Mon code sans les guillemets. Le second échoue car il n'y a pas d'utilisateur appelé « "» (guillemet double) pour ~"mapper.

Jonathan Leffler
la source
8

Après avoir lutté avec le même problème, j'ai essayé deux solutions différentes qui fonctionnent:

1. Utilisez des guillemets doubles ( "") avec vos variables.

Le moyen le plus simple de double guillemet vos variables comme indiqué dans la réponse précédente:

cd "$yourPathWithBlankSpace"

2. Utilisez eval.

Selon cette réponse Commande Unix pour échapper des espaces, vous pouvez supprimer les espaces vides puis utiliser eval, comme ceci:

yourPathEscaped=$(printf %q "$yourPathWithBlankSpace")
eval cd $yourPathEscaped
HanniBaL90
la source
4

Un seul backslash fonctionne pour moi:

ry4an@ry4an-mini:~$ mkdir "My Code"

ry4an@ry4an-mini:~$ vi todir.sh

ry4an@ry4an-mini:~$ . todir.sh 

ry4an@ry4an-mini:My Code$ cat ../todir.sh 
#!/bin/sh
cd ~/My\ Code

Êtes-vous sûr que le problème n'est pas que votre script shell change de répertoire dans son sous-shell, mais vous êtes de retour dans le shell principal (et le répertoire d'origine) une fois terminé? J'ai évité cela en utilisant. pour exécuter le script dans le shell actuel, bien que la plupart des gens utilisent simplement un alias pour cela. Les espaces pourraient être un hareng rouge.

Ry4an Brase
la source
Merci, Ry4an (et le reste des répondants). Il semble que j'exécutais le script de manière incorrecte. J'essayais juste de l'exécuter comme ceci:% ./cdsomedir Je n'avais pas réalisé que je devais utiliser le "." pour exécuter le script comme vous l'avez fait:%. cdsomedir.sh Une fois que j'ai fait cela, cela a fonctionné. Erreur de débutant. Merci!
3

Évitez ~ dans les scripts; utilisez plutôt $ HOME.

Chris FA Johnson
la source
2

Lorsque vous travaillez sous Linux, la syntaxe ci-dessous est correcte:

cd ~/My\ Code

Cependant, lorsque vous exécutez votre fichier, utilisez la syntaxe ci-dessous:

$ . cdcode

(juste "." et non "./")

Alterlife
la source
Par curiosité sauvage, pourquoi est-ce important? Je n'ai jamais vu que «./» utilisé.
whaley
./ créera un nouveau shell, puis changera de répertoire. Ainsi, lorsque le script se termine, il retourne au shell qui a engendré le nouveau shell ... vous serez dans le répertoire où vous avez exécuté le script au lieu de ~ / My Code. '.' d'autre part provoque l'exécution du script dans l'instance courante du shell.
Alterlife
Le point "." est une commande unix, un alias pour la commande "source". Il doit être suivi d'un nom de fichier. Donc "source myfile" exécutera le fichier dans votre shell actuel. Et ". Myfile" fera de même. La variable "./" signifie "répertoire courant" et n'est pas une commande.
JPGConnolly
2

utiliser des guillemets doubles

go () 
{ 
    cd "$*"
}
Bobo
la source
Merci. Un ajout utile aux fonctions d'un .bashrcfichier pour changer de répertoire lors du collage de noms de répertoires contenant des espaces sur la ligne de commande sans avoir à ensuite échapper les espaces ou citer le tout. cdsest un meilleur nom cependant.
mattst
Existe-t-il un moyen d'étendre cela (sans if) de telle sorte que ce soit juste goéquivalent à cd, c'est- à -dire, cd vers le répertoire personnel?
zennehoy
2

La manière très simple de procéder est-

 $ cd My\ Folder

Dans bash, exécutez la commande DIR et dans les résultats, vous verrez que les noms de dossier ou de chemin ayant un espace entre eux ont été écrits dans les résultats comme ceci -

$dir
My\ Folder
New\ Folder
Mayukh Datta
la source
2

Cela le fera:

cd ~/My\ Code

J'ai dû l'utiliser pour travailler avec des fichiers stockés sur iCloud Drive. Vous ne voudrez pas utiliser de guillemets doubles (") car il doit s'agir d'un chemin absolu. En d'autres termes, vous ne pouvez pas combiner des guillemets doubles avec le tilde (~).

A titre d'exemple, j'ai dû utiliser ceci pour un projet récent:

cd ~/Library/Mobile\ Documents/com~apple~CloudDocs/Documents/Documents\ -\ My\ iMac/Project

J'espère que cela aide.

Josh
la source
1

J'avais un problème similaire maintenant si j'utilisais un script bash pour vider certaines données. J'ai fini par créer un lien symbolique dans le dossier du script sans aucun espace. J'ai ensuite pointé mon script vers le lien symbolique et cela fonctionne très bien.

Pour créer votre lien. ln -s [RÉPERTOIRE OU FICHIER CIBLE] ./[SHORTCUT]

Mau ou peut ne pas être utile.


la source
0

Utilisez des guillemets simples, comme:

myPath=~/'my dir'

cd $myPath
Jadian
la source