J'ai ce script shell enregistré dans un fichier: il fait une substitution de chaîne de base.
#!/bin/sh
html_file=$1
echo "html_file = $html_file"
substr=.pdf
pdf_file="${html_file/.html/.pdf}"
echo "pdf_file = $pdf_file"
Si je le colle dans la ligne de commande, cela fonctionne très bien:
$ html_file="/home/max/for_pauld/test_no_base64.html"
echo "html_file = $html_file"
substr=.pdf
pdf_file="${html_file/.html/.pdf}"
echo "pdf_file = $pdf_file"
donne
html_file = /home/max/for_pauld/test_no_base64.html
pdf_file = /home/max/for_pauld/test_no_base64.pdf
C'est la sortie d'écho ci-dessus - cela fonctionne comme prévu.
Mais, quand j'appelle le script, avec
$ saucer "/home/max/for_pauld/test_no_base64.html"
J'obtiens cette sortie:
html_file = /home/max/for_pauld/test_no_base64.html
/home/max/bin/saucer: 5: /home/max/bin/saucer: Bad substitution
Mon script utilise-t-il une version différente de bash ou quelque chose? Dois-je changer ma ligne de shebang?
sh
etbash
. Je vais le lire. Si vous pouvez prendre la peine de faire de votre commentaire une réponse, je le marquerai correctement.#!/usr/bin/env bash
comme votre shebang et utilisez des substitutions définies de manière posix comme vous le souhaitez, mais avec des mises en garde de portabilité. Et lisez: unix.stackexchange.com/a/48787/27616Réponses:
Quel est sh
sh
(ou Shell Command Language) est un langage de programmation décrit par la norme POSIX . Il a de nombreuses implémentations (ksh88
,dash
, ...).bash
peut également être considérée comme une implémentation desh
(voir ci-dessous).Parce que
sh
c'est une spécification, pas une implémentation,/bin/sh
est un lien symbolique (ou un lien dur) vers une implémentation réelle sur la plupart des systèmes POSIX.Qu'est-ce que bash
bash
a commencé comme unesh
implémentation compatible (bien qu'elle soit antérieure au standard POSIX de quelques années), mais avec le temps, elle a acquis de nombreuses extensions. Beaucoup de ces extensions peuvent changer le comportement des scripts shell POSIX valides, donc en soibash
n'est pas un shell POSIX valide. Il s'agit plutôt d'un dialecte du langage shell POSIX.bash
prend en charge un--posix
commutateur, ce qui le rend plus conforme à POSIX. Il essaie également d'imiter POSIX s'il est appelé en tant quesh
.sh = bash?
Pendant longtemps,
/bin/sh
utilisé pour pointer/bin/bash
sur la plupart des systèmes GNU / Linux. En conséquence, il était devenu presque sûr d'ignorer la différence entre les deux. Mais cela a commencé à changer récemment.Voici quelques exemples populaires de systèmes sur lesquels
/bin/sh
ne pointe pas/bin/bash
(et dont certains/bin/bash
peuvent même ne pas exister):sh
versdash
par défaut;initramfs
. Il utilise l'ash
implémentation du shell.pdksh
, un descendant du shell Korn. FreeBSDsh
est un descendant du shell UNIX Bourne d'origine. Solaris a la siennesh
qui, pendant longtemps, n'était pas compatible POSIX; une implémentation gratuite est disponible à partir du projet Heirloom .Comment pouvez-vous savoir ce qui
/bin/sh
pointe sur votre système?La complication est que cela
/bin/sh
pourrait être un lien symbolique ou un lien dur. S'il s'agit d'un lien symbolique, un moyen portable de le résoudre est:Si c'est un lien dur, essayez
En fait, le
-L
drapeau couvre à la fois les liens symboliques et les liens durs, mais l'inconvénient de cette méthode est qu'elle n'est pas portable - POSIX n'a pas besoinfind
de prendre en charge l'-samefile
option, bien que GNU find et FreeBSD find la prennent en charge.Ligne Shebang
En fin de compte, c'est à vous de décider lequel utiliser, en écrivant la ligne «shebang».
Par exemple
utilisera
sh
(et quoi que ce soit qui pointe),utilisera
/bin/bash
s'il est disponible (et échouera avec un message d'erreur s'il ne l'est pas). Bien sûr, vous pouvez également spécifier une autre implémentation, par exempleLequel utiliser
Pour mes propres scripts, je préfère
sh
pour les raisons suivantes:bash
, ils doivent avoirsh
Il y a aussi des avantages à utiliser
bash
. Ses fonctionnalités rendent la programmation plus pratique et similaire à la programmation dans d'autres langages de programmation modernes. Ceux-ci incluent des éléments tels que des variables et des tableaux locaux étendus. Plainsh
est un langage de programmation très minimaliste.la source
/bin/sh
est en effet un lien symbolique vers/bin/dash
.Pour ajouter à l'excellente réponse de @ Hunter.S.Thompson, je voudrais souligner que la partie non portable du script est
C'est
${variable/search/replace}
une extension GNU. Mais vous pouvez facilement l'éviter avec POSIX pur:Après Hunter, c'est la meilleure solution que de changer le shebang en
#! /bin/bash
la source