Exécuter des scripts depuis un autre répertoire

10

Très souvent, le script que je veux exécuter ne se trouve pas dans mon répertoire de travail actuel et je ne veux pas vraiment le quitter.

Est-ce une bonne pratique d’exécuter des scripts (BASH, Perl, etc.) à partir d’un autre répertoire? Trouvent-ils généralement tout ce dont ils ont besoin pour fonctionner correctement?

Si tel est le cas, quel est le meilleur moyen de lancer un script "distant"? Est-ce

. /path/to/script

ou

sh /path/to/script

et comment utiliser sudodans de tels cas? Ceci, par exemple, ne fonctionne pas:

sudo . /path/to/script
Desmond Hume
la source
Sachez que les . /path/to/script sources du script! Vous n'avez pas du tout besoin de période si vous voulez simplement l'exécuter.
gniourf_gniourf

Réponses:

13

sh / path / to / script va engendrer un nouveau shell et exécuter son script indépendamment de votre shell actuel. La sourcecommande (.) Appellera toutes les commandes du script dans le shell actuel. Si le script appelle exitpar exemple, vous perdez le shell actuel. Pour cette raison, il est généralement plus sûr d'appeler des scripts dans un shell séparé avec sh ou de les exécuter en tant que fichiers binaires à l'aide du chemin complet (à partir de /) ou relatif (./). Appelés en tant que fichiers binaires, ils seront exécutés avec l'interpréteur spécifié (#! / Bin / bash, par exemple).

Quant à savoir si un script trouvera ou non les fichiers dont il a besoin, il n’ya pas de bonne réponse à part regarder le script pour voir ce qu’il fait. En option, vous pouvez toujours accéder au dossier du script dans un sous-processus sans quitter votre dossier actuel:

$(cd /wherever/ ; sh script.sh)
Рослав Рахматуллин
la source
3
Tu veux dire (cd /wherever/ ; sh script.sh)? Pourquoi as-tu un $devant?
G-Man
7

Vous pouvez certainement le faire (avec les ajustements que les autres ont mentionnés, comme sudo sh /pathto/script.shou ./script.sh). Cependant, je fais une des choses pour les exécuter sur tout le système pour ne pas m'inquiéter des répertoires et me épargner une saisie inutile.

1) Lien symbolique vers /usr/bin

ln -s /home/username/Scripts/name.sh /usr/bin/name

(assurez-vous qu'il n'y a pas de noms qui se chevauchent, car vous auriez évidemment le remplacer.) Cela me permet également de les conserver dans mes dossiers de développement afin de pouvoir les ajuster si nécessaire.

2) Ajoutez le répertoire Scripts à votre chemin (en utilisant .bash_profile - ou le fichier que vous avez.profile sur votre shell)

PATH=/path/to/scripts/:$PATH

3) Créer des alias .bash_profile dans ~/.bash_profileajouter quelque chose comme:

alias l="ls -l"

Comme vous pouvez le constater, la syntaxe est simplement alias, les chiffres que vous souhaitez utiliser comme commande, la commande. Si vous tapez "l" n'importe où dans le terminal, vous obtiendrez ls -l Si vous voulez sudo, alias sl="sudo ls -l"notez simplement l vs sl (exemple inutile).

De toute façon, vous pouvez simplement taper sudo nameofscriptet être sur votre chemin. Pas besoin de jouer avec ./ ou. ou sh, etc. Il suffit de les marquer comme exécutables en premier: D

nerdwaller
la source
Je recommande vivement l'option 2.
Bernhard
Pourquoi ?, c'est une pratique exemplaire ou juste du goût?
Sergio
3

Je fais habituellement comme tu dis

sh /path/to/script

Et pour l'exécuter en tant que root / superutilisateur

sudo sh /path/to/script

Votre répertoire actuel n’a d’importance que si les scripts supposent que vous êtes dans le même dossier. Je suppose que la plupart des scripts ne le font pas et que vous êtes sûr de l'exécuter comme ci-dessus.

Bolli
la source
ne fonctionnerait pas si chemin_sécurisé était défini dans le fichier / etc / sudoers
l1zard
3

Je conserve généralement mes scripts dans /usr/local/binou /usr/local/sbin/(si le script nécessite des privilèges root), conformément au standard FHS (Filesystem Hierarchy Standard), ils appartiennent.

Tout ce que vous avez à faire est de vous assurer que ces deux répertoires sont ajoutés à votre PATH. Vous pouvez le faire en modifiant votre $HOME/.bashrcfichier et en ajoutant cette ligne:

export PATH=$PATH:/usr/local/sbin:/usr/local/bin

Si vous voulez pouvoir exécuter un script en tant que root via sudo, vous devez ajouter ces répertoires à la variable secure_pathdans votre fichier /etc/sudoers.

Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

La modification de ce fichier se fait en exécutant, visudoce qui évite les erreurs.

l1zard
la source
Typo: tu veux dire .bashrcau lieu de .bachrc.
gniourf_gniourf
0

Je ne suis pas sûr que cela fonctionne comme cela sous Linux, en supposant que ce ne soit pas le cas si personne ne le suggère. Mais au lieu d'utiliser ././ pour revenir aux répertoires. Pouvez-vous utiliser des guillemets pour lui donner un chemin absolu? Peut-être que cela ne vous donne pas accès à l'intégralité du disque dur, même pour pouvoir le faire, à bien y penser.

Codezilla
la source
0

Si vous avez des scripts que vous devez exécuter souvent, et qu'ils dépendent de leur emplacement pour trouver des ressources, vous pouvez facilement le faire en combinant simplement des commandes dans un alias comme celui-ci.

alias run-script="cd /home/user/path/to/script/ && bash script.sh"

De cette façon, vous n'avez rien à changer pour que cela fonctionne.

EvR2f
la source
0

Vous ne savez pas pourquoi personne n'a suggéré celui-ci, mais c'est super facile! J'ai googlé quelques fois et je ne trouvais pas la réponse exacte que je donnais, alors je pensais partager. OMI, ceci mais la meilleure solution, aussi la plus facile, pour moi de toute façon, mais d’autres peuvent se sentir et faire les choses différemment.

# Place this somewhere in your .bashrc/.bash_profile/etc and edit as you see fit

YOURCOMMAND () {
  cd /path/to/directory/containing/your/script/ && ./YOURSCRIPT
}

Tout d'abord, la commande 'cd' lui indique le répertoire de l'emplacement des scripts. Puis '&&' pour pouvoir le lier après avoir exécuté la commande suivante. Enfin, ouvrez votre script comme vous le feriez dans un terminal! Vous avez enregistré votre dans votre fichier BASH et l’installation prend 5 secondes.

J'espère que cela a aidé quelqu'un.

AnonymousX
la source
-1

Ancienne question, mais intemporelle.

La solution que j’ai toujours vue est d’avoir un $HOME/binrépertoire et de le placer en premier $PATH(via ~/.bashrcsi ce n’est pas déjà fait; sur certains systèmes, il ~/binest premier $PATHpar défaut). Le fait d’y déposer des scripts pour l’exécution ou de créer des liens symboliques vers des scripts / exécutables est un moyen simple de traiter les problèmes de chemin qui ne devraient pas affecter le système ni les autres utilisateurs.

Si un script nécessite des ressources supplémentaires pouvant être trouvées par rapport à son propre emplacement (pas inhabituel), la variable d'environnement $BASH_SOURCEest utilisée. $BASH_SOURCEcontient toujours le chemin absolu du script en cours d'exécution, quelle que soit la valeur de $PWD.

Considérer ce qui suit:

ceverett@burrito:~$ echo $PATH
/home/ceverett/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

Nous pouvons donc voir que $HOME/binc'est le premier arrivé $PATH, donc tout ce que je mets ~/binsera utilisé. J'ai un script de démonstration appelé ~/bin/findme:

#!/bin/bash

echo "Running from $BASH_SOURCE"

Ceci peut être utilisé pour obtenir le chemin absolu vers l'emplacement du script en cours d'exécution.

ceverett@burrito:~$ findme
Running from /home/ceverett/bin/findme
ceverett@burrito:~$ cd foo
ceverett@burrito:~/foo$ findme
Running from /home/ceverett/bin/findme
ceverett@burrito:~/foo$ cd /
ceverett@burrito:/$ findme
Running from /home/ceverett/bin/findme
zxq9
la source
(1) Bien que cela semble être une information utile, la question ne demandait pas comment écrire des scripts qui utilisent des ressources par rapport à leur propre emplacement; il a demandé à propos de l'exécution des scripts. (2) Je ne sais pas comment votre deuxième paragraphe répond à la question. Êtes-vous en train de suggérer que, si j'écris un script et que Desmond souhaite l'exécuter, il devrait le relier à son binrépertoire privé ? Cela semble lourd. (3) En outre, cela brise l'indépendance de la localisation. Si /home/desmond/bin/fooest un lien vers mon script, alors le BASH_SOURCEsera /home/desmond/bin/foo, et le script ne pourra pas trouver ses ressources.
G-Man
@ G-Man (1) L'utilisateur n'a pas fourni beaucoup de contexte. Chaque fois que cette question m’a été posée au cours des 30 dernières années, c’est toujours dans le contexte d’un utilisateur (généralement un nouveau sysop ou un développeur) qui exécute un mélange de ses propres scripts et d’autres scripts acquis pour automatiser des tâches triviales; façon. Cela fait prendre un peu de connaissances de script de la part de l'utilisateur demandé. (2) Les scripts système sont généralement installés dans /binou dans un emplacement connu /opt. (3) L’indépendance d’emplacement est exactement ce que cela préserve lors de l’écriture d’une collection interdépendante de scripts personnels.
Zxq9