shopt fonctionne en ligne de commande, introuvable lors de l'exécution dans un script

13

shopt -s dotglob J'écris un script pour copier des fichiers, et j'essaie d'utiliser pour permettre à cp de copier des fichiers dot comme .jshintet ainsi de suite.

Je peux exécuter shopt -s dotglobdirectement à une invite bash sans erreur. Cependant, l'exécution du script génère l'erreur:

script.sh: 81: script.sh: shopt: not found

J'exécute ce script en shell bash, avec l'en-tête shebang #!/usr/bin/env bash. Ligne d'erreur:

shopt -s dotglob
cp -r $TEMP/img/* $TARGET/img/
cp -r $TEMP/js/* $TARGET/js/
cp -r $TEMP/less/* $TARGET/less/

Vous ne trouvez rien d'utile sur Google, vous savez quel est le problème ici?

Kurtosis
la source
Merci pour le rappel, des réponses sélectionnées pour tout ce que j'ai pu. Encore une à part cette question qui n'a pas encore de bonne réponse.
Kurtosis
3
Essayez avec l'en- #!/bin/bashtête plus simple ?
ish
Et quelle version d'Ubuntu?
ish
2
@izx, qui est la bonne réponse, shoptest une commande intégrée bash, shn'a pas shopt, et le message d'erreur ressemble à un message d'erreur de dash. Il est donc très probable que l'erreur ici exécute un script bash avec sh(qui, dashpar défaut, dans Ubuntu ). Même s'il shs'agit d'un lien symbolique vers bash, exécuter un script bash avec shn'est pas la même chose que l'exécuter avec bash.
geirha

Réponses:

23

Pour former une réponse à partir des commentaires:

Beaucoup de gens par habitude exécutent leurs scripts avec shau lieu de bash. C'est une bonne pratique si la portabilité est un problème, mais beaucoup de gens le font parce qu'ils copient quelque chose qu'ils ont vu sans le comprendre.

À moins que votre script ne doive s'exécuter sur un système Linux autre que le bureau (par exemple, exécuter des scripts shell sur des appareils Android est assez différent), je recommande d'utiliser la ligne Bash shebang au début:

#!/bin/bash

Cette ligne, lorsqu'elle est la première ligne du script, détermine quel interpréteur (shell tel que bash ou sh, Python, etc.) est appelé pour l'exécuter. Si vous utilisez la ligne ci-dessus, vous obtiendrez (presque) le même comportement que vous le faites à partir de la ligne de commande, en supposant que vous utilisez le shell par défaut. Si, pour des raisons de portabilité ou de préférence, vous utilisez une ligne de shebang différente, sachez que vous devrez consulter la documentation du shell que vous avez référencé, même si le shell que vous référencez est un lien symbolique vers Bash.

Scott Severance
la source
5
Pour être complètement multi-système, je préfère: #!/usr/bin/env bash comme c'est le travail d'env de savoir quel bash utiliser (au cas où vous l'auriez corrigé, par exemple).
shrikeh
-1

Vous devez quitter zsh et activer bash comme indiqué:

exec bash

L'exécuter la commande

source ~/.bashrc

Après quoi, vous pouvez réactif zsh:

exec zsh

J'espère que cela pourra aider

David Kabii
la source
Hmmm. 1) Je ne pense pas que l'OP utilisait zsh, 2) AFAIK ~/.basrcest exécuté par bash au démarrage dans ce cas, donc il n'est pas nécessaire de l'appeler explicitement, 3) où la commande de l'OP est-elle exécutée? et 4) l'utilisation de execdeux fois vous fait perdre tous les changements d'environnement que vous avez effectués dans le shell zsh initial, ce qui ne se produirait pas si vous appeliez simplement bash.
xenoid
Dans mon cas, il était nécessaire de détecter les changements d'environnement et les changements ont persisté. Je viens de redémarrer l'ordinateur et toutes mes modifications sont conservées. Peut-être que c'est juste spécifique à anaconda que j'essayais de configurer
David Kabii