Pourquoi dois-je mettre sh avant d'exécuter les fichiers .sh?


16

Lorsque je veux exécuter des .shfichiers dans Terminal, je dois les placer shdevant eux.

Existe-t-il un moyen d'éviter cela et donc d'économiser la frappe?


3
J'ai créé un dossier dans ~ / bin pour y mettre mes scripts shell et le mettre sur mon $ PATH et j'ai également attaché une action de dossier au dossier ~ / bin pour définir automatiquement les autorisations d'exécution parce que c'est si facile d'oublier de le faire.
Kaydell

Réponses:


22

Si vous exécutez votre script à partir du shell, vous n'avez pas vraiment besoin du #!/bin/shshebang comme indiqué dans cette réponse - chaque système de type Unix que j'ai utilisé, y compris OS X, sera par défaut /bin/shsi aucun interpréteur n'est spécifiquement spécifié ( bien que ce soit une bonne idée car les non-shells ne sauront pas comment exécuter votre script à moins que vous ne donniez le shebang.)

Vous n'avez pas non plus besoin d'une .shextension. Vous avez besoin de définir des autorisations exécutables, par exemple

$ chmod +x script.sh

(Le $est l'invite du shell; je l'utilise pour illustrer les commandes que vous donnez au shell interactif. Ne le tapez pas!)

Cependant, je pense que votre confusion est que vous avez créé un script, par exemple script.sh, dans le répertoire courant, et que vous essayez de l'exécuter en tapant simplement script.sh. par exemple

$ cat >script.sh
echo hello, world
^D
$ chmod +x script.sh
$ script.sh
-bash: script.sh: command not found

( ^Dsignifie control- D. Vous trouverez cette notation dans de nombreux écrits sur l'utilisation d'Unix.)

Le fait que script.shdans ce cas est un script shell n'est que la moitié du problème; votre problème réel est que, par défaut, le shell ne recherchera pas le programme actuel pour un programme. Cependant, cela fonctionne:

$ sh script.sh
hello, world

car shprend le script comme argument.

Vous pouvez exécuter un script - ou, encore une fois, n'importe quel exécutable - dans le répertoire en cours, s'il est marqué comme exécutable (c'est-à-dire chmod +x), en spécifiant que vous voulez exécuter celui du répertoire en cours:

$ ./script.sh
hello, world

Vous pouvez également déplacer le script vers un répertoire de votre PATH. Je recommande /usr/local/binpour cela si votre script est destiné à être utilisé à l'échelle du système, ou un binrépertoire dans votre maison si le script est uniquement pour vous. Ce dernier vous oblige à ajouter $HOME/bin, qui s'étend à votre nouveau répertoire bin, à votre PATHen ajoutant les lignes suivantes à votre .profiledans votre répertoire personnel:

PATH=$HOME/bin:$PATH
export PATH

Enfin, vous pouvez, si vous le souhaitez, ajouter réellement le répertoire courant à votre PATH, ce qui vous permettra d’aller simplement dans un répertoire contenant script.sh- ou tout autre exécutable - et de taper

$ script.sh

pour l'exécuter. Cependant, je ne recommande pas cette pratique , car un attaquant peut maintenant vous inciter à exécuter un exécutable arbitraire en déposant un script exécutable (nommé, disons ls) dans un répertoire dans lequel vous vous trouverez. Si vous voulez vraiment le faire, cependant, ajoutez simplement ce qui suit à votre .profile:

PATH=.:$PATH
export PATH

Mettez le '.' à la fin du $ PATH au lieu du début et maintenant vous n'avez plus à vous soucier d'un 'ls' fantôme. (Bien que si quelqu'un peut entrer dans votre système, vous avez de plus gros problèmes.)
TJ Luoma

2
@TJ, mais vous ne devez vous soucier des choses comme slou llsou l... à savoir, les fautes de frappe. Il suffit de laisser .sur $PATH. De plus, vous pouvez (ou ne devriez pas) faire nécessairement confiance à tout le monde sur votre système. Par exemple, supposons qu'il existe un exploit qui permet à un attaquant de déposer un fichier arbitraire dans un répertoire, mais qu'il a besoin de vous pour exécuter ce fichier afin de dégénérer en un meilleur exploit (par exemple, collecter des données et appeler le téléphone). Défense en profondeur!
Reid

@TJLuoma Ce que @Reid a dit, et gardez à l'esprit qu'il existe de nombreux cas d'utilisation pour un système Unix au-delà d'un bureau OS X personnel. Je ne l'ai pas essayé, mais je parie que même le compte invité pourrait laisser l'un de ces éléments dans /tmpun autre répertoire accessible en écriture.
zigg

Si vous utilisez un système où d'autres personnes ont accès aux répertoires que vous utilisez, vous avez des problèmes plus importants.
TJ Luoma

@TJLuoma Il vaut donc mieux ne jamais utiliser plusieurs comptes sur un système Unix. /tmpet al. venir avec le territoire.
zigg

10

Vous n'avez pas besoin d'appeler shsi le fichier de script est marqué comme exécutable. Dans ce cas, vous pouvez l'appeler mon nom comme vous le feriez pour n'importe quelle autre commande du shell existant.


Pour être pleinement correct, vous voudrez faire deux choses:

  1. Modifiez votre script pour inclure une directive shebang en haut de votre script:

    #!/bin/sh

    ... Cela indiquerait au shell quel interpréteur utiliser pour exécuter le script; dans ce cas, l' /bin/shexécutable.

  2. Marquez le script comme exécutable par vous avec la commande chmod :

    chmod u+x scriptname.sh

Une fois que vous avez effectué ces deux opérations, vous devriez pouvoir exécuter votre script en tapant le nom de fichier de votre script sur la ligne de commande. Vous devrez être dans le même répertoire que votre script, à moins que vous ne preniez également l'étape supplémentaire d'ajouter le dossier contenant à votre variable PATH . Si vous ne vous souciez pas du shell qui exécute le script, vous n'avez pas besoin de la première étape pour le spécifier, shmais il est souvent préférable d'être précis et de définir le "shebangsh".


Les bangs ne sont pas vraiment nécessaires pour /bin/sh, bien qu'ils ne blessent pas.
zigg

@zigg - Vous avez raison. J'espère que Chris ne me dérange pas mes modifications… Nuke ou ré-éditer comme vous le souhaitez: -0
bmike

@bmike Les modifications fonctionnent pour moi. En ce qui concerne les shebangs, mon habitude était de toujours spécifier car j'avais l'habitude d'écrire beaucoup de kshscripts à l'époque sur HP-UX - mais il est bon de savoir que ce n'est pas strictement nécessaire.
Chris W. Rea

1
Je pense que je dois revenir sur ma déclaration précédente sur la nécessité de shebang (bien que le reste de ma réponse soit toujours valable.) Vous pouvez exécuter un script sans shebang à partir d'un shell, mais si vous utilisez un execsyscall, vous obtenez ENOEXEC(erreur de format exec ). Désolé pour ça, @bmike, @ ChrisW.Rea. Je vais modifier ma réponse maintenant.
zigg
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.