Bash scripting shebang - bash

I have this simple script:
#!/bin/dash
echo "Shell used:" $SHELL
I expected to get:
Shell used: /bin/dash
But instead of the output is:
Shell used: /bin/bash
I'm running the script as:
./my_script.sh

Related

Bash pass argument to --init-file script

I'm running a shell script using bash --init-file script.sh that runs some commands, then leaves an interactive session open. How can I pass arguments to this init file from the process that runs the initial bash command? bash --init-file 'script.sh arg' doesn't work.
Interestingly, if the script contains echo "$# $*", passing an argument as I did above causes it to print nothing, while not passing an argument prints '0'.
Create a file with the content:
#!/bin/bash
script.sh arg
Pass that file to bash: bash --init-file thatfile
I'd like the arg to come from the command that runs bash with the
Create a file from the command line and pass it:
arg="$1"
cat >thatfile <<EOF
$(declare -p arg)
script.sh \"\$arg\"
EOF
bash --init-file thatfile
You might be interested in researching what is a process substitution in bash.

bash script doesn't act like shell

Here is my script:
#!/bin/bash
x="aabcaa"
y=${x##*(a)}
echo $y
It outputs aabcaa when I expect bcaa.
When I try the same commands on a bash shell (got with bash command from zsh shell), everything works as I want. I checked the version with bash --version and /bin/bash --version. Obviously, the two commands output the same thing. The unexpected behavior of the script is the same in a zsh shell and in a bash shell.
What could be wrong?

Saving the result of an echo command in a shell script?

I am attempting to store the result of an echo command as a variable to be used in a shell script. Debian 4.19.0-6-amd64
The command works in terminal: echo $HOSTNAME returns debian-base, the correct hostname.
I attempt to run it in a shell script, such as:
#!/usr/bin/bash
CURRENT_HOSTNAME=`echo $HOSTNAME`
echo $CURRENT_HOSTNAME
I have tried expansion:
CURRENT_HOSTNAME=$(echo $HOSTNAME)
And just to cover some more bases, I tried things like:
CURRENT_HOSTNAME=$HOSTNAME
# or
CURRENT_HOSTNAME="$HOSTNAME"
# also, in case a problem with reserved names:
test=$HOSTNAME
test="$HOSTNAME"
Works great in the terminal! Output is as follows:
root#debian-base:/scripts# echo $HOSTNAME
debian-base
root#debian-base:/scripts# TEST_HOSTNAME=$HOSTNAME
root#debian-base:/scripts# echo $TEST_HOSTNAME
debian-base
root#debian-base:/scripts# TEST_TWO_HOSTNAME=$(echo $HOSTNAME)
root#debian-base:/scripts# echo $TEST_TWO_HOSTNAME
debian-base
As soon as I run the script (as above):
root#debian-base:/scripts# sh test.sh
root#debian-base:/scripts#
What am I doing wrong?
You are using bash as your terminal. Bash has the variable $HOSTNAME set. You run your script with sh. sh does not have a $HOSTNAME.
Options:
bash test.sh
Or run it as a program:
chmod +x test.sh
./test.sh
But I think you need to change your first line to:
#!/bin/bash
As I don't think bash is installed in /usr/bin in most cases. But you need to try. To figure out where bash is installed use which bash
Another option is to use the hostname binary:
CURRENT_HOSTNAME=$(hostname)
echo $CURRENT_HOSTNAME
Which works in both bash and sh.
You can start sh by just running sh. You will see it has a bash-like terminal. You can try to do echo $HOSTNAME. It will not show, because it's not there. You can use set to see all the variables that are there (as sh does not have tab completion it's harder to figure out).

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

Blank first line of shell script: explain behavior of UID variable

I have two very simple scripts, differing only by the presence of a blank first line:
$ cat test.bash
#!/bin/bash
echo ${UID}
$ cat test_blank.bash
#!/bin/bash
echo ${UID}
Now I run then, with and without nice:
$ ./test.bash
1060
$ ./test_blank.bash
1060
$ nice ./test.bash
1060
$ nice ./test_blank.bash
Please explain why, in the final case, the UID variable is unset. The behavior is the same when replacing nice with sudo or nohup.
Observe:
$ bash test_blank.bash
1060
$ dash test_blank.bash
bash produces output but dash, which is the default sh on debian-like systems, does not. This is because bash sets UID but dash does not. (POSIX does not require a shell to set UID.) So, the question becomes which shell executes the script.
When bash sees ./test.sh, it (bash) runs the script. When another command, such as nice, receives the script as an argument and the script does not have a valid shebang as the first line, then the default shell, likely dash, is run.
If you want UID in dash, or any other shell that does not provide it, use the id command:
UID=$(id -u)
Finding out which shell is running a script
To see which shell is running a script, use:
$ cat test2.sh
#!/bin/bash
ps $$
echo UID=${UID}
Under bash:
$ ./test2.sh
PID TTY STAT TIME COMMAND
1652 pts/12 S+ 0:00 bash -rcfile .bashrc
UID=1060
If we invoke it using nice, by contrast, we can see that it is running under /bin/sh and the UID variable is not assigned:
$ nice test2.sh
PID TTY STAT TIME COMMAND
1659 pts/12 SN+ 0:00 /bin/sh test2.sh
UID=

Resources