The following script.sh is executed:
#!/bin/bash
set -eu
# code ...
su buser
mkdir /does/not/work
echo $?
echo This should not be printed
Output:
1
This should not be printed
How i execute the script:
docker exec -i fancy_container bash < script.sh
Question: Why does the script not terminate after the failing command even when set -e was defined and how can i get the script to exit on any failing command? I think the key point is the '<' operator, which i do not understand exactly how it executes the script.
Notes:
-e means: Abort script at first error, when a command exits with non-zero status (except in until or while loops, if-tests, list constructs)
Possible solution:
docker exec -i fancy_container bash -c "cat > tmp.sh; bash tmp.sh" < script.sh
How it works:
< script.sh - Pipe all rows of this file from the host, to the docker exec command.
cat > tmp.sh - Save the incoming piped content to a file inside the container.
bash tmp.sh - Execute the file as-whole inside the container, which means -e works again as expected!
But i still don't know why the initial approach isn't working.
I want to run these two command in a loop:
for i in cat input:
do
winpty Kubectl exec -it $i -n image -c podname -- sh
2nd command
done
When I am running the .sh file, the first command works fine and after than nothing is happening.Can anybody help on this?I am running through gitbash from windows machine
I'm a bash rookie, but maybe it's because of the lack of a defined -d directory for unzipped files?
I am trying to do the following:
if ps aux | grep "[t]ransporter_pulldown.py" > /dev/null
then
echo "Script is already running. Skipping"
else
exec "sudo STAGE=production $DIR/transporter_pulldown.py" # this line errors
fi
$ sudo STAGE=production $DIR/transporter_pulldown.py works on the command line, but in a bash script it gives me:
./transporter_pulldown.sh: line 9:
exec: /Users/david/Desktop/Avails/scripts/STAGE=production
/Users/david/Desktop/Avails/scripts/transporter_pulldown.py:
cannot execute: No such file or directory
What would be the correct syntax here?
sudo isn't a command interpreter thus its trying to execute the first argument as a command.
Instead try this:
exec sudo bash -c "STAGE=production $DIR/transporter_pulldown.py"
This creates uses a new bash processes to interpret the variables and execute your python script. Also note that $DIR will be interpreted by the shell you're typing in rather than the shell that is being executed. To force it to be interpreted in the new bash process use single quotes.
I made a bash script to generate an ssh that I use all the time with a couple options. At the end it echos a string for whatever it is going to execute, and then it executes it. Currently I'm trying to add the functionality to add in a bash command to run once the ssh is completed, but its giving an error like so:
bash: /bin/echo 'hello'; bash -l: No such file or directory
Yet if I copy the command it runs, and run it from outside the executable, it runs perfectly. Is there any reason I would be getting this error from inside the executable, and not from the CLI?
An example command it generates is:
pair -c "/bin/echo 'hello'"
Running: ssh ****##.#.#.# -p443 -t "/bin/echo 'hello'; bash -l"
This is most likely caused because of too strong quoting. This error line
bash: /bin/echo 'hello'; bash -l: No such file or directory
shows that bash does not try to execute the command /bin/echo with the argument 'hello' followed by the command bash -l. Instead bash is trying to execute the command /bin/echo 'hello'; bash -l.
Compare:
$ ssh localhost -t "/bin/echo 'foo'; bash -l"
foo
$ logout # this is the new shell
Connection to localhost closed.
and:
$ ssh localhost -t '"/bin/echo 'foo'; bash -l"'
bash: /bin/echo foo; bash -l: No such file or directory
Connection to localhost closed.
The solution to this problem usually involves eval, but I cannot tell for sure unless I see more code from you.
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?
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!
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.
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.
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!
do it the simpler way,
direc=$(basename `pwd`)
Or use the shell
$ direc=${PWD##*/}
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...
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.
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
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.