Function runs on CLI but not from bash script - bash

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.

Related

sed shell with jenkins deployment

I'm working on something at the moment and just now I even wonder if what I am working on is even possible.
I want to SSH from jenkins to a shell script and use variables form a rc file that are in a git Repository. (The Shell script and rc file are in the same repo)
Nothing that I tried works and now I'm starting to wondering if it's even possible.
Here's is my local script but i get the same output on jenkins.
docker exec -it test-container bash 'sed -f <(printf "s/${DOMAIN}\.%s/www.&.${DOMAIN_SUFFIX_STAGE}/g\n" ${LANG_KEYS}) /var/www/foo/sed/test.txt > /var/www/foo/sed/new-2.txt'
No matter what I do I get this error
bash: sed -f <(printf "s/${DOMAIN}\.%s/www.&.${DOMAIN_SUFFIX_STAGE}/g\n" ${LANG_KEYS}) /var/www/foo/sed/test.txt > /var/www/foo/sed/new-2.txt: No such file or directory
And yes I can confirm that the directory is there
Here's an easier way to reproduce your problem:
$ bash "echo Hello"
bash: echo Hello: No such file or directory
This happens because the expected syntax is bash yourfile. The string you are passing is not a useful filename, so it fails.
To run a string argument as a command, you can use bash -c commandstring:
$ bash -c "echo Hello"
Hello
This makes bash interpret the parameter as a shell command to execute, instead of a filename to open.

How to execute Zsh shell commands in Bash Script

I want to execute Zsh function command in Bash script. Here is an example:
~/.zshrc
hello () {
echo "Hello!"
}
hello.sh
#!/bin/bash
hello
executing above bash script in zsh
(zsh) $ ./hello.sh
hello command not found
I also tried with heredocs:
#!/bin/bash
/bin/zsh - <<'EOF'
hello
EOF
executing above script with heredocs also says command not found error.
Any suggestions?
Thanks!
You can use it like that :
#!/bin/bash
/bin/zsh -i -c hello
-i : Force shell to be interactive
Then, if the shell is interactive, commands are read from /etc/zshrc and then $ZDOTDIR/.zshrc (this is usually your $HOME/.zshrc)
-c : Run a command in this shell

Proper syntax for bash exec

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.

How to specify zeroeth argument

I'm writing a bash script that starts the tcsh interpreter as a login shell and has it execute my_command. The tcsh man page says that there are two ways to start a login shell. The first is to use /bin/tcsh -l with no other arguments. Not an option, because I need the shell to execute my_command. The second is to specify a dash (-) as the zeroeth argument.
Now the bash exec command with the -l option does exactly this, and in fact the following works perfectly:
#!/bin/bash
exec -l /bin/tcsh -c my_command
Except... I can't use exec because I need the script to come back and do some other things afterwards! So how can I specify - as the zeroeth argument to /bin/tcsh without using exec?
You can enclose the exec command into a sub-shell of your script.
#!/bin/bash
(exec -l /bin/tcsh -c my_command)
# ... whatever else you need to do after the command is done
You can write a wrapper (w.sh) script that contains:
#!/bin/bash
exec -l /bin/tcsh -c my_command
and execute w.sh in your main script.

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?
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.

Resources