Trouble Passing Parameter into Simple ShellScript (command not found) - macos

I am trying to write a simple shell-script that prints out the first parameter if there is one and prints "none" if it doesn't. The script is called test.sh
if [$1 = ""]
then
echo "none"
else
echo $1
fi
If I run the script without a parameter everything works. However if I run this command source test.sh -test, I get this error -bash: [test: command not found before the script continues on and correctly echos test. What am I doing wrong?

you need spaces before/after '[',']' chars, i.e.
if [ "$1" = "" ] ; then
#---^---------^ here
echo "none"
else
echo "$1"
fi
And you need to wrap your reference (really all references) to $1 with quotes as edited above.
After you fix that, you may also need to give a relative path to your script, i.e.
source ./test.sh -test
#------^^--- there
When you get a shell error message has you have here, it almost always helps to turn on shell debugging with set -vx before the lines that are causing your trouble, OR very near the top your script. Then you can see each line/block of code that is being executed, AND the value of the variables that the shell is using.
I hope this helps.

Related

Jenkins Execute shell if then statement fails with `Bad substitution`

I need an if statement in Jenkins Execute Shell, but it always fails on the same line, regardless of what’s there.
I’m trying to do something like this:
if [ " ${BuildVariants[*]} " =~ " VariantA " ]; then
# fails on this line even this line is just a comment
variant_config=""
fi
it fails when I try to assign a variable there, fails when I try to echo "anything", fails even on comment (as example above)
Reason: Bad substitution
Note: There's anything specified in Configure System, so it should be using default Bash.
What the problem might be?
I don't think =~ works inside of [ ... ] -- use [[ ... ]] instead.
Shellcheck is a great tool for find these types of things; it would show that you've hit SC2074.
re:
fails on this line even this line is just a comment
You cannot have an "empty" then block. You can use just : as code to be executed:
if [[ "$foo" == "bar" ]]; then
:
fi
Next idea: get your code to run in a shell script, then put the code up in Jenkins. You will probably need to mock up some of the Jenkins-supplied input to do that, but it takes one more moving part out of the equation. If the code runs from the command line and doesn't in Jenkins, then you need to start looking for Jenkins-specific causes, like maybe it's being run in a csh instead of Bash (I see you mention this specific possibility already, but maybe there's something else like it -- I don't know Jenkins, sorry).
So the problem was that I supposed Jenkins was giving me an array, but it was giving me a string. (I used with Extended Choice Parameter, with multiple choices).
So the condition should've been [[ "$BuildVariants" == *"VariantA"* ]].

Why can't a string variable be evaluated as a command when using ${!variable}?

This is somehow related to Use substituted string as a command in shell script I asked last year. That accepted answer worked nicely.
#!/usr/bin/env bash
for user in ytu
do
cd /home/${user}/H2-Data/crons
for path in "$user"_*_monthly_report.py
do
if [ -e $path ]
then
. ../../.profile
userpython=${user^^}_PYTHON
echo ${!userpython} $path
else
break
fi
done
done
This echos what I expected:
/home/ytu/anaconda3/bin/python ytu_clinic217_monthly_report.py
/home/ytu/anaconda3/bin/python ytu_clinic226_monthly_report.py
However, by simply changing ${user^^}_PYTHON to $YTU_PYTHON, which should be exactly the same in this case, the bash script now echos:
ytu_clinic217_monthly_report.py
ytu_clinic226_monthly_report.py
I even tried userpython=/home/ytu/anaconda3/bin/python but that ends up the same. That said, if I echo $userpython, I can still get /home/ytu/anaconda3/bin/python in the latter cases.
I wonder why can't userpython be evaluated anymore by simply assigning the variable explicitly, and how can I make it right?

Shell script working only after adding an echo statement just before body of the 'if' block

I am trying to run the below script but it is not executing the if block but when I add another statement echo "Test" just below the if statement then my if block gets executed. Can anyone suggest what is causing this? I am not able to figure out how adding an echo statement is making the if block execute.
P.S. Please assume that the source and target directories exist and the file also exists in the source directory with the same name as mentioned in the script.
Script not Working:
if [ -f $/apps/agile/product/xxxxxx.xlsx ]
then
mv /apps/agile/product/xxxxxx.xlsx /apps/agile/product/Archived
echo "Moved the last generated Report to Archived Directory"
fi;
Working Script:
if [ -f $/apps/agile/product/xxxxxx.xlsx ]
echo "Test"
then
mv /apps/agile/product/xxxxxx.xlsx /apps/agile/product/Archived
echo "Moved the last generated Report to Archived Directory"
fi;
The argument to if is a sequence of commands. The exit status of the last one of these commands is what if examines and acts on.
You are effectively changing
if false; then
to
if false; true; then
which succeeds.
The real cause of the error is probably the aberrant $/ at the beginning of the path. We can't guess what the correct path is, but this is almost certainly incorrect, unless you really have a directory named $ in the current directory (which would be hugely impractical).

Use a shell output value in shell script

If I try following:
varReturn=$(ls)
echo $varReturn
it shows me the correct output of the listed elements in the directory.
But if I try this one:
varReturn=$(/opt/vc/bin/tvservice -n)
echo $varReturn
it doesn't show me the expected output :/
My goal is to check if an HDMI Port is connected or not.
It' very curious for me, why it works only for some commands.
I'm looking forward to getting some help here. I didn't figure out, what the problem is.
EDIT:
Now I've found another way and tried following:
varReturn=`tvservice -s`
echo $varReturn
this shows me the correct output:
But if I use another command, like this one:
varReturn=`tvservice -n`
echo $varReturn
It shows me no output at echo, but the output from the var (confusing).
It still shows me the output if I use following code:
varReturn=`tvservice -n`
#echo $varReturn
The output is shown without the blank space.
There is at least one problem with this code:
varReturn=$(/opt/vc/bin/tvservice -n)
echo $varReturn
# ^ missing double quotes around this variable
Adding those quotes will ensure that the variable is passed as a single argument to echo. Otherwise, echo sees a list of arguments and outputs each one, separated by a space.
The next possible issue is that the command is outputting to standard error, rather than standard output, so it won't be captured by $() or the old-fashioned equivalent ` `. To correct this, try:
output=$(/opt/vc/bin/tvservice -n 2>&1)
# ^ redirect standard error to standard output
echo "$output"
When you execute a shell command like varReturn=$(/opt/vc/bin/tvservice -n)
it will store the output to the variable only when the command executed successfully, else it will not hold any information because error/unsuccessful message will be redirected to standard error. Hence you have to redirected it to standard output like below:-
varReturn=$(/opt/vc/bin/tvservice -n 2>&1)
Now in both successful and unsuccessful execution case output will store in variable varReturn.

Why is executing a ruby command on bash to command file not working?

Code from .command file:
cd "$(dirname "$0")"
g1=Hi-Lo
echo Welcome to Ruby_Games! So far, you can play $g1.
echo What game would you like to play?
read game_choice
if [$game_choice == $g1]
then
ruby Hi-Lo.rb
fi
Output:
Welcome to Ruby_Games! So far, you can play Hi-Lo.
What game would you like to play?
Hi-Lo
/Users/Abbas/Desktop/Ruby_Games/LAUNCHER.command: line 6: [Hi-Lo: command not found
logout
So what exactly is going wrong? Thanks
I believe you need double quotes in your if statement
Similar to example 6.4 here: http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-6.html
cd "$(dirname "$0")"
g1=Hi-Lo
echo Welcome to Ruby_Games! So far, you can play $g1.
echo What game would you like to play?
read game_choice
if [ "$game_choice" = "$g1" ]
then
ruby Hi-Lo.rb
fi
You need spaces between each element of the test (aka [) command. That is, you need a space between [ and $game_choice, between $game_choice and =, etc. Also, as #GregHNZ pointed out, you should use double-quotes around variable references, in case they contain spaces or certain other shell metacharacters. Finally, == in a test expression is a bash extension; use = instead, and it'll work in more basic shells as well. Result:
if [ "$game_choice" = "$g1" ]
Spaces are important delimiters in shell syntax; there are places they're required and places they're forbidden, and very very few places where they're optional. In many languages, you can add or remove spaces to make the code more readable, but that's not the case in shell.
BTW, I recommend using shellcheck.net; it does a pretty good job of spotting errors like this. Actually, it points out a couple I didn't think of: you should add a shebang line to the beginning of the script, and using cd without checking for an error risks the rest of the script running in an unexpected directory. So you should use something like this:
#!/bin/bash
cd "$(dirname "$0")" || {
echo "Error cd'ing to the script's directory" >&2
exit 1
}

Resources