2008-11-17 15 views
3

Je script shell qui commence par:`(cd X, PWD)` retourne parfois deux lignes

sdir=`dirname $0` 
sdir=`(cd "$sdir/"; pwd)` 

Et cela se généralement élargi (avec 'sh -h') dans

++ dirname /opt/foo/bin/bar 
+ sdir=/opt/foo/bin 
++ cd /opt/foo/bin/ 
++ pwd 
+ sdir=/opt/foo/bin 

mais pour un seul utilisateur à la combinaison unique de paramètres en se dilate en (note deux lignes à la valeur de résultat) sbin

++ dirname bin/foo 
+ sdir=bin 
++ cd bin/ 
++ pwd 
+ sdir='/opt/foo/bin 
/opt/foo/bin' 

I essayé différents combinaisons mais n'a pas été en mesure de reproduire ce comportement. Avec différents paramètres d'entrée pour cet utilisateur, il a commencé à produire un résultat de ligne unique correct. Je suis nouveau à shell scripting, donc s'il vous plaît avis quand un tel (cd X; pwd) peut renvoyer deux lignes. il a été observé sur CentOS, mais pas sûr que ce soit important. Veuillez nous conseiller

+0

Notez que les parenthèses dans la deuxième ligne ne sont pas nécessaires - les guillemets vous donnent déjà un sous-shell et le deuxième niveau gaspille simplement de l'énergie. Une fraction minuscule d'un peu d'énergie, mais ... –

Répondre

0

Il est possible que l'utilisateur ait un alias funky pour "cd". Peut-être que vous pourriez essayer de faire "/ usr/bin/cd" (ou tout "cd" tourne par défaut) à la place.

+0

cd est un shell intégré; il n'y a pas d'exécutable séparé car il doit être exécuté par le shell lui-même. (cd dans un sous-processus n'affecte pas le processus parent). Néanmoins, l'item 'alias for cd' est plausible. Correction par unalias, probablement. –

+0

ou utilisez le mot-clé bash 'builtin' –

0

Certaines personnes alias pwd "echo $ PWD". En outre, la commande pwd elle-même peut être un shell intégré ou un programme dans/usr/bin. Faites un "alias pwd" et "quel pwd" à la fois sur cet utilisateur et tout utilisateur qui fonctionne normalement.

5

Le coupable est cd, essayez cette place

sdir=`dirname $0` 
sdir=`(cd "$sdir/" >/dev/null; pwd)` 

Cela se produit parce que lorsque vous spécifiez un chemin non absolu et le répertoire se trouve dans l'environnement variable CDPATH, imprime cd à stdout la valeur du chemin absolu dans le répertoire où il a été changé.

pertinentes sections bash homme:

 
     CDPATH The search path for the cd command. This is a 
       colon-separated list of directories in which the 
       shell looks for destination directories specified 
       by the cd command. A sample value is ``.:~:/usr''. 

     cd [-L|-P] [directory] 

       Change the current working directory to directory. If 
       directory is not given, the value of the HOME shell 
       variable is used. If the shell variable CDPATH exists, 
       it is used as a search path. If directory begins with a slash, 
       CDPATH is not used. 

       The -P option means to not follow symbolic links; symbolic 
       links are followed by default or with the -L option. If 
       directory is ‘-’, it is equivalent to $OLDPWD. 

       If a non-empty directory name from CDPATH is used, or if ‘-’ 
RELEVANT -\ is the first argument, and the directory change is successful, 
PARAGRAPH -/ the absolute pathname of the new working directory is written 
       to the standard output. 

       The return status is zero if the directory is successfully 
       changed, non-zero otherwise. 

     OLDPWD The previous working directory as set by the cd 
       command. 

1

CDPATH est une Gotcha commune. Vous pouvez également utiliser "CDPATH non installé, exporter CDPATH" pour éviter le problème dans votre script.

+0

Pourquoi exportez-vous la variable précédemment non définie? – jlliagre

+0

Parce que je ne comprends pas la commande d'exportation, et comment cela fonctionne dans tous les différents shells. Je sais que 'unset' s'appliquera aux variables locales dans le shell. Je ne sais pas s'il fera automatiquement les mêmes modifications dans l'environnement exporté. Il était donc plus sûr d'utiliser la commande d'exportation. –

+0

Okay. Vous pouvez supprimer cette déclaration inutile ici. "unset" effacera la variable de l'environnement sur tous les shells compatibles Bourne/POSIX et c'est ce que vous voulez ici. "export" va recréer cette variable dans l'environnement avec un contenu vide qui semble inutile. – jlliagre

0

Essayez ceci:

sdir=$(cd $(dirname "$0") > /dev/null && pwd) 

Il est juste une seule ligne et gardera tous les caractères spéciaux dans le nom du répertoire intact. Rappelez-vous que sous Unix, seuls deux caractères sont illégaux dans un nom de fichier/répertoire: 0 octet et / (barre oblique). Surtout, les nouvelles lignes sont valides dans un nom de fichier!

+0

utilisez '&&' au lieu de ';' dans le cas où la commande cd échoue. –