How to view the command executed in a script as it is executed? - bash

I have a bash script I've written to automate something tedious, so I got the command looking right in echo, but when I run it, it doesn't work. This is what I'm doing:
CMD='custom_script update --flag=value --comment="testing"'
echo -e "Running $CMD"
$CMD
The echo shows:
custom_script update --flag=value --comment="testing"
which is correct, but that is not what is actually run with the $CMD line (I know because if I copy and paste the output from echo, it works, but the error message after running in the script suggests the quoting is off).
I think I can figure this out if I can see the command run by $CMD, but I don't know how to do that.

Run it like
bash -x script.sh
or modify the shebang like
#!/bin/bash -x

Looks like
eval $CMD
is what I needed.

Related

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

Allow user input in second command in bash pipe

I'm looking for how I might allow user input in a second command in a bash statement and I'm not sure how to go about it. I'd like to be able to provide a one-liner for someone to be able to install my application, but part of that application process requires asking some questions.
The current script setup looks like:
curl <url/to/bootstrap.sh> | bash
and then boostrap.sh does:
if [ $UID -ne 0 ]; then
echo "This script requires root to run. Restarting the script under root."
exec sudo $0 "$#"
exit $?
fi
git clone <url_to_repo> /usr/local/repo/
bash /usr/local/repo/.setup/install_system.sh
which in turn calls a python3 script that asks for input.
I know that the the curl in the first line is using stdin and so that might make what I'm asking impossible and that it has to be two lines to ever work:
wget <url/to/boostrap.sh>
bash bootstrap.sh
You can restructure your script to run this way:
bash -c "$(curl -s http://0.0.0.0//test.bash 2>/dev/null)"
foo
wololo:a
a
My test.bash is really just
#!/bin/bash
echo foo
python -c 'x = raw_input("wololo:");print(x)'`
To demonstrate that stdin can be read from in this way. Sure it creates a subshell to take care of curl but it allows you to keep reading from stdin as well.

BASH get error code in parent terminal from child terminal?

In a bash script I start a new terminal with a command that gives an error. However I don't seem to be able to grab that error code:
#! /bin/bash
gnome-terminal -x bash -c "cat dksdamfasdlm"
echo $?
Output:
0
So I get the error code of the gnome-terminal command instead of the cat one. One suggestion I got, was to make a file with the code and read that from the parent bash. The problem is that I still seem to not be able and read the error code even that way:
#! /bin/bash
gnome-terminal -x bash -c "cat dksdamfasdlm; echo $?; sleep 2"
Output (on new terminal):
cat: dksdamfasdlm: No such file or directory
0
Why is that? Some suggestion on how to solve this? I just want to somehow grab the error in the new terminal from the parent bash.
It seems GNOME Terminal exits immediately after starting, which is obvious if you run for example gnome-terminal -x sleep 10. Since it doesn't wait for the command to finish, there's no way the return code will be that of the command. I could find no option in gnome-terminal --help-all to keep the process in the foreground.
Regarding your second question, you've double-quoted the command, so $? is expanded before running it. This should work:
gnome-terminal -x bash -c 'cat dksdamfasdlm; echo $?; sleep 2'
PS: The -x option is not documented in GNOME Terminal 3.8.4's gnome-terminal --help-all, various references don't help much, and there's no good explanation for why there's a -e option with identical semantics and different syntax.

How can I resolve this error in shell scripting: "read: Illegal option -t"?

#!/bin/bash
echo -n "Hurry up and type something! > "
if read -t 10 response ; then
echo "Greate, you made it in time!"
else
echo "sorry, you are too slow!"
fi
I have written above code in terminal and got error "read: Illegal option -t".
Bash supports -t, so it looks like you're trying to execute it with sh or some other shell, which is odd, since you have the correct shebang.
Make sure you run it with ./script or path_to_script/script. If you just run it in the terminal, first start bash.
I had the same problem and then I figured out that I was using #!/bin/sh instead of #!/bin/bash. After changing the shebang everything worked as desired.
bash supports the -t option for the read builtin since version bash-2.04 (see ChangeLog), so either you are using an ancient version of bash (<= 2.03) or are not really running your script under bash.
Run bash --version to check the version and double-check that your shebang really looks like #!/bin/bash in your script.

bash echo not displaying values

When I run the following script, echo does not display anything and I don't know why. It works if I just type it into the terminal, but not from the shell script. Need some insight please. I might be tired but I'm very certain this should work:
#!/bin/sh
for n in `seq 1 10`
do
r=$RANDOM
t=$RANDOM
s=$RANDOM
f=$RANDOM
echo "$r $t $s $f"
done
echo "Done"
Your terminal probably runs a different shell than /bin/sh. For example, on Ubuntu, /bin/sh runs /bin/dash, but $RANDOM does not work there. You have to run /bin/bash or /bin/ksh to make it work.
When run from a terminal, you probably use bash, not sh.
Seems sh doesn't support $RANDOM and thus all variables you assign in your script will be assigned the empty string. Try changing the first line of your script to #!/bin/bash (or whereever bash is installed).

Resources