Bash: erreur de syntaxe: redirection inattendue

138

Je fais cela dans un script:

read direc <<< $(basename `pwd`)

et j'obtiens:

Syntax error: redirection unexpected

dans une machine ubuntu

/bin/bash --version
GNU bash, version 4.0.33(1)-release (x86_64-pc-linux-gnu)

alors que je n'obtiens pas cette erreur dans une autre machine suse:

/bin/bash --version
GNU bash, version 3.2.39(1)-release (x86_64-suse-linux-gnu)
Copyright (C) 2007 Free Software Foundation, Inc.

Pourquoi l'erreur?

Ouvrez la voie
la source
Pour référence, la commande fonctionne également sur cygwin (/ bin / bash --version GNU bash, version 3.2.49 (23) -release (i686-pc-cygwin) Copyright (C) 2007 Free Software Foundation, Inc.)
hlovdal

Réponses:

243

Votre script fait-il référence /bin/bashou /bin/shdans sa ligne de hachage? Le shell système par défaut dans Ubuntu est dash , pas bash , donc si vous en avez, #!/bin/shvotre script utilisera un shell différent de celui que vous attendez. Dash n'a pas l' <<<opérateur de redirection.

John Kugelman
la source
14

Docker:

J'avais ce problème de mon Dockerfile comme j'avais:

RUN bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)

Cependant, selon ce problème , il a été résolu:

Le formulaire exec permet d'éviter le munging de chaîne shell, et les RUN commandes utilisant une image de base qui ne contient pas/bin/sh .

Remarque

Pour utiliser un autre shell, autre que /bin/sh, utilisez le formulaire exec en passant le shell souhaité. Par exemple,

RUN ["/bin/bash", "-c", "echo hello"]

Solution:

RUN ["/bin/bash", "-c", "bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)"]

Notez les guillemets autour de chaque paramètre.

fantôme de kemicofa
la source
14

Si vous utilisez ce qui suit pour exécuter votre script:

sudo sh ./script.sh

Ensuite, vous voudrez utiliser ce qui suit à la place:

sudo bash ./script.sh

La raison en est que Bash n'est pas le shell par défaut pour Ubuntu. Donc, si vous utilisez "sh", il utilisera simplement le shell par défaut; qui est en fait Dash. Cela se produira peu importe si vous avez #!/bin/bashen haut de votre script. En conséquence, vous devrez spécifier explicitement d'utiliserbash comme indiqué ci-dessus, et votre script doit s'exécuter comme prévu.

Dash ne prend pas en charge les redirections de la même manière que Bash.

Chris Pietschmann
la source
6

Vous pouvez obtenir la sortie de cette commande et la placer dans une variable. puis utilisez heredoc. par exemple:

nc -l -p 80 <<< "tested like a charm";

peut être écrit comme:

nc -l -p 80 <<EOF
tested like a charm
EOF

et comme ça (c'est ce que vous voulez):

text="tested like a charm"
nc -l -p 80 <<EOF
$text
EOF

Exemple pratique en busyboxsous dockerconteneur:

kasra@ubuntu:~$ docker run --rm -it busybox
/ # nc -l -p 80 <<< "tested like a charm";
sh: syntax error: unexpected redirection


/ # nc -l -p 80 <<EOL
> tested like a charm
> EOL
^Cpunt!       => socket listening, no errors. ^Cpunt! is result of CTRL+C signal.


/ # text="tested like a charm"
/ # nc -l -p 80 <<EOF
> $text
> EOF
^Cpunt!
AmirHossein
la source
... ou echo 'text' | ncqui est encore plus court.
phil294
2

faites-le de la manière la plus simple,

direc=$(basename `pwd`)

Ou utilisez la coque

$ direc=${PWD##*/}
ghostdog74
la source
1

Une autre raison de l'erreur peut être si vous exécutez une tâche cron qui met à jour une copie de travail de subversion et que vous avez ensuite tenté d'exécuter un script versionné qui était dans un état de conflit après la mise à jour ...

Motin
la source
1

Sur ma machine, si j'exécute un script directement, la valeur par défaut est bash .

Si je l'exécute avec sudo, la valeur par défaut est sh.

C'est pourquoi je rencontrais ce problème lorsque j'utilisais sudo.

Michael Mather
la source
0

Dans mon cas, l'erreur est due au fait que j'ai mis ">>" deux fois

mongodump --db=$DB_NAME --collection=$col --out=$BACKUP_LOCATION/$DB_NAME-$BACKUP_DATE >> >> $LOG_PATH

je viens de le corriger comme

mongodump --db=$DB_NAME --collection=$col --out=$BACKUP_LOCATION/$DB_NAME-$BACKUP_DATE >> $LOG_PATH
Mansur Ali
la source
0

Avant d'exécuter le script, vous devez vérifier la première ligne du script shell pour l'interpréteur.

Ex: si les scripts commencent par / bin / bash, exécutez le script en utilisant la commande ci-dessous "bash nom_script.sh"

si le script commence par / bin / sh, exécutez le script en utilisant la commande ci-dessous "sh nom_script.sh"

./sample.sh - Cela détectera l'interpréteur à partir de la première ligne du script et l'exécutera.

Différentes distributions Linux ayant différents shells par défaut.

Sijeesh
la source
1
Bien que nous vous remercions pour votre réponse, il serait préférable qu'elle apporte une valeur supplémentaire en plus des autres réponses. Dans ce cas, votre réponse n'apporte pas de valeur supplémentaire, puisqu'un autre utilisateur a déjà publié cette solution. Si une réponse précédente vous a été utile, vous devriez la voter au lieu de répéter les mêmes informations.
Toby Speight
Ne pensez-vous pas que j'ai expliqué la solution ici avec un exemple?
Sijeesh
Y a-t-il quelque chose ici qui ne soit pas suffisamment couvert dans la réponse de John Kugelman écrite il y a 8 ans?
Toby Speight