ChatGPT解决这个技术问题 Extra ChatGPT

Bash: Syntax error: redirection unexpected

I do this in a script:

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

and I get:

Syntax error: redirection unexpected

in an ubuntu machine

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

while I do not get this error in another suse machine:

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

Why the error?

For reference, the command works on cygwin as well ( /bin/bash --version GNU bash, version 3.2.49(23)-release (i686-pc-cygwin) Copyright (C) 2007 Free Software Foundation, Inc. )

J
John Kugelman

Does your script reference /bin/bash or /bin/sh in its hash bang line? The default system shell in Ubuntu is dash, not bash, so if you have #!/bin/sh then your script will be using a different shell than you expect. Dash does not have the <<< redirection operator.

Make sure the shebang line is:

#!/bin/bash

or

#!/usr/bin/env bash

And run the script with:

$ ./script.sh

Do not run it with an explicit sh as that will ignore the shebang:

$ sh ./script.sh   # Don't do this!

I have "#!/bin/bash" on top the sh file, but it still gives that error. It worked when used bash ./script.sh as @chris's said.
@ibilgen Are you running it with sh ./script.sh? Don't run scripts with an explicit shell. Just type the script name ./script.sh so it can use the interpreter declared in the shebang line.
Should I change default shell dash to bash?
@kittygirl I just changed from '/bin/sh' to '/bin/bash' and it worked!!
No, don't change the default shell. This is a bug in the script / how the script is run. Don't make global changes to fix a local problem.
C
Chris Pietschmann

If you're using the following to run your script:

sudo sh ./script.sh

Then you'll want to use the following instead:

sudo bash ./script.sh

The reason for this is that Bash is not the default shell for Ubuntu. So, if you use "sh" then it will just use the default shell; which is actually Dash. This will happen regardless if you have #!/bin/bash at the top of your script. As a result, you will need to explicitly specify to use bash as shown above, and your script should run at expected.

Dash doesn't support redirects the same as Bash.


T
Toby Speight

Docker:

I was getting this problem from my Dockerfile as I had:

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

However, according to this issue, it was solved:

The exec form makes it possible to avoid shell string munging, and to RUN commands using a base image that does not contain /bin/sh. Note To use a different shell, other than /bin/sh, use the exec form passing in the desired shell. For example, 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)"]

Notice the quotes around each parameter.


This made it possible for me to get the here-string running inside a Dockerfile. That here-string was needed for saying "yes" (y) to an "overwrite question" (not important: it was for ssh-keygen -q -t rsa <<< ""$'\n'"y", see stackoverflow.com/a/43235320/11154841).
A
AmirHossein

You can get the output of that command and put it in a variable. then use heredoc. for example:

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

can be written like:

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

and like this (this is what you want):

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

Practical example in busybox under docker container:

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!

...or echo 'text' | nc which is even shorter.
g
ghostdog74

do it the simpler way,

direc=$(basename `pwd`)

Or use the shell

$ direc=${PWD##*/}

M
Motin

Another reason to the error may be if you are running a cron job that updates a subversion working copy and then has attempted to run a versioned script that was in a conflicted state after the update...


M
Milo

On my machine, if I run a script directly, the default is bash.

If I run it with sudo, the default is sh.

That’s why I was hitting this problem when I used sudo.


l
luk2302

In my case error is because i have put ">>" twice

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

i just correct it as

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

S
Sijeesh

Before running the script, you should check first line of the shell script for the interpreter.

Eg: if scripts starts with /bin/bash , run the script using the below command "bash script_name.sh"

if script starts with /bin/sh, run the script using the below command "sh script_name.sh"

./sample.sh - This will detect the interpreter from the first line of the script and run.

Different Linux distributions having different shells as default.


Though we thank you for your answer, it would be better if it provided additional value on top of the other answers. In this case, your answer does not provide additional value, since another user already posted that solution. If a previous answer was helpful to you, you should vote it up instead of repeating the same information.
Don't you think that I explained the solution here with an example?
Is there anything here that isn't adequately covered in John Kugelman's answer written 8 years ago?