This question already has answers here:
Difference between sh and Bash
(11 answers)
Closed 2 years ago.
The community is reviewing whether to reopen this question as of yesterday.
I'm working with a bash script that is currently working on a server (RHEL4). I'm developing on my laptop with Ubuntu 10.04, but I don't think the platform is causing the problem.
Here's what's happening:
I have a skeleton script that calls another script that does most of the work. However, it makes calls to getConfig.sh a lot. getConfig.sh basically just parses some command line argument (using getopts) and calls a Java program to parse some XML files. Anyways, getConfig.sh is throwing up lots of errors (but still seems to work).
Here's the message that I'm getting
getconfig.sh: 89: [[: not found
getconfig.sh: 89: [[: not found
getconfig.sh: 94: [[: not found
I get those three errors every time it runs; however, the script completes and the Java code runs.
Here's the relavent code section
parseOptions $*
if [[ "${debugMode}" == "true" ]] ; then
DEBUG="-DDEBUG=true"
echo "${JAVA_HOME}/bin/java ${DEBUG} -Djava.endorsed.dirs=${JAXP_HOME} -jar $(dirname $0)/GetXPath.jar ${XML_File} ${XPath_Query}"
fi
Line 89 is "parseOptions $* and line 94 is "fi"
Thanks for the answers.
If your script is executable and you are executing it like ./getconfig.sh, the first line of your script needs to be:
#!/bin/bash
Without that shebang line, your script will be interpreted by sh which doesn't understand [[ in if statements.
Otherwise, you should run your script like bash getconfig.sh, not sh getconfig.sh. Even if your default shell is bash, scripts run with sh will use a reduced set of bash's features, in order to be more compliant with the POSIX standard. [[ is one of the features that is disabled.
Use:
bash scriptname.sh
instead of:
sh scriptname.sh
If you are checking for equality, shouldn't the if be ?
if [[ "${debugMode}" = "true" ]]; then
....
fi
Related
This question already has answers here:
How to if/else statement in shell script
(5 answers)
Closed 3 months ago.
I'm brand new to shell scripting and I've looked up some tutorials about basic shell scripting, but my script still is not running. I'm not totally sure what I'm doing wrong. I'm trying to crack a CTF for some context. The error I'm getting is "line 10: syntax error near unexpected token `done'"
Does anyone have any tips on how to fix this or any resources that could point me in the correct direction?
#!/bin/bash
i=0
while :
do
if [[ "$(md5sum < (echo -n "${i}d470d406"))" =~ "0badbeef" ]] ; then
echo $i
break
let i+=1
done
I tried to run this script and am getting the error stated above.
You have to close the if with fi.
Paste your script on https://www.shellcheck.net/
This question already has answers here:
Difference between sh and Bash
(11 answers)
Closed 2 years ago.
i'm coding a simple bash script and i found this error syntax error at line XX `(' unexpected
my code:
function myfun(){
echo XXXX
echo YYYY
read choice
}
choice=$(myfun)
where is the error. i used the ShellCheck and no errors were detected.
Make sure you are running the script with bash. That error is a commonly seen dash shell error.
I suspect the first line of your script is not #!/bin/bash, i.e. you may have left out the shebang line entirely resulting in the default shell being used (which will often be dash especially on Debian derived Linuxes where /bin/sh -> dash).
Try running this:
#!/bin/bash
myfun()
{
echo XXXX
echo YYYY
read choice
}
choice=$(myfun)
This question already has an answer here:
Find "command not found" when executed in bash loop
(1 answer)
Closed 3 years ago.
I made a simple script in linux bash just like bellow:
#!/bin/bash
PATH=/tmp_with_zip_files
FILETYPE=zip
i=1
for filename in $PATH/*.$FILETYPE;
do
echo "rm $filename";
if [ -f $filename ];
then rm $filename;
fi
i=$((i+1))
done
echo "$i files removed"
But, when i run script i have error, because script doesnt work correctly. It's mean from console i have a message:
zip_delete.sh: line 11: rm: command not found
Why linux bash script not recognize linux command rm?
Lol I think it's because you're overwriting the default $PATH variable (which is the variable that tells bash where to look for executables). During execution, it can't find the rm program in PATH because it's pointing to only /tmp_with_zip_files
Use a different variable name for your purposes like chicken_nuggets.
WARNING DON'T DO THE FOLLOWING LMAO PATH=$PATH:/tmp_with_zip_files you could delete a bunch of things from PATH and that would suck really bad
The PATH variable holds the path to OS commands (like rm), don't use that as a variable, name it something else, like path_to_files.
This question already has answers here:
Pass commands as input to another command (su, ssh, sh, etc)
(3 answers)
Closed 6 years ago.
I'm very very new to Linux(coming from windows) and trying to write a script that i can hopefully execute over multiple systems. I tried to use Python for this but fount it hard too. Here is what i have so far:
cd /bin
bash
source compilervars.sh intel64
cd ~
exit #exit bash
file= "~/a.out"
if[! -f "$file"]
then
icc code.c
fi
#run some commands here...
The script hangs in the second line (bash). I'm not sure how to fix that or if I'm doing it wrong. Please advice.
Also, any tips of how to run this script over multiple systems on the same network?
Thanks a lot.
What I believe you'd want to do:
#!/bin/bash
source /bin/compilervars.sh intel64
file="$HOME/a.out"
if [ ! -f "$file" ]; then
icc code.c
fi
You would put this in a file and make it executable with chmod +x myscript. Then you would run it with ./myscript. Alternatively, you could just run it with bash myscript.
Your script makes little sense. The second line will open a new bash session, but it will just sit there until you exit it. Also, changing directories back and forth is very seldom required. To execute a single command in another directory, one usually does
( cd /other/place && mycommand )
The ( ... ) tells the shell that you'd like to do this in a sub-shell. The cd happens within that sub-shell and you don't have to cd back after it's done. If the cd fails, the command will not be run.
For example: You might want to make sure you're in $HOME when you compile the code:
if [ ! -f "$file" ]; then
( cd $HOME && icc code.c )
fi
... or even pick out the directory name from the variable file and use that:
if [ -f "$file" ]; then
( cd $(dirname "$file") && icc code.c )
fi
Assigning to a variable needs to happen as I wrote it, without spaces around the =.
Likewise, there needs to be spaces after if and inside [ ... ] as I wrote it above.
I also tend to use $HOME rather than ~ in scripts as it's more descriptive.
A shell script isn't a record of key strokes which are typed into a terminal. If you write a script like this:
command1
bash
command2
it does not mean that the script will switch to bash, and then execute command2 in the different shell. It means that bash will be run. If there is a controlling terminal, that bash will show you a prompt and wait for a command to be typed in. You will have to type exit to quit that bash. Only then will the original script then continue with command2.
There is no way to switch a script to a different shell halfway through. There are ways to simulate this. A script can re-execute itself using a different shell. In order to do that, the script has to contain logic to detect that it is being re-executed, so that it can prevent re-executing itself again, and to skip some code that shouldn't be run twice.
In this script, I implemented such a re-execution hack. It consists of these lines:
#
# The #!/bin/sh might be some legacy piece of crap,
# not even up to 1990 POSIX.2 spec. So the first step
# is to look for a better shell in some known places
# and re-execute ourselves with that interpreter.
#
if test x$txr_shell = x ; then
for shell in /bin/bash /usr/bin/bash /usr/xpg4/bin/sh ; do
if test -x $shell ; then
txr_shell=$shell
break
fi
done
if test x$txr_shell = x ; then
echo "No known POSIX shell found: falling back on /bin/sh, which may not work"
txr_shell=/bin/sh
fi
export txr_shell
exec $txr_shell $0 ${#+"$#"}
fi
The txr_shell variable (not a standard variable, my invention) is how this logic detects that it's been re-executed. If the variable doesn't exist then this is the original execution. When we re-execute we export txr_shell so the re-executed instance will then have this environment variable.
The variable also holds the path to the shell; that is used later in the script; it is passed through to a Makefile as the SHELL variable, so that make build recipes use that same shell. In the above logic, the contents of txr_shell don't matter; it's used as Boolean: either it exists or it doesn't.
The programming style in the above code snippet is deliberately coded to work on very old shells. That is why test x$txr_shell = x is used instead of the modern syntax [ -z "$txr_shell" ], and why ${#+"$#"} is used instead of just "$#".
This style is no longer used after this point in the script, because the
rest of the script runs in some good, reasonably modern shell thanks to the re-execution trick.
This question already has answers here:
Why does /bin/sh behave differently to /bin/bash even if one points to the other?
(4 answers)
Closed 6 years ago.
When I execute my script sh myscript.sh I get an error message which states that [[: is an 'unexpected operator', however when i run my script in a bash emulator (http://www.tutorialspoint.com/execute_bash_online.php) it works and doesn't return this error. Furthermore, when i run the script using sh within the emulator it works and doesn't return the error even though on my server it would.
I've checked the link below and, from what i understand, i need to use the bash command. What is wrong with the sh command and how do i enable functions such as [[: to be executed?
NOTE: I am a student and therefore i can only run the bash terminal in school. So any help that will guarantee that this error will not be returned will be hugely appreciated.
[ :Unexpected operator in shell programming
Simple answer is to just use bash myscript.sh. As has been mentioned below, the [[ syntax is bash specific, and not supported by sh.
These are two separate shells, each with their own variation on the scripting language. A vulgar analogy would be that bash is to sh, what c++ is to c. Bash has more features, and some easier syntax, but they share a lot in common.
If you have #!/bin/bash at the top of your file, then it's a bash script. You run this by entering bash yourscript.sh if it is not executable, or simply ./yourscript.sh if it is.
If you have #!/bin/sh, then it's an sh script. You run this by the same principles described above.
You could think about it like this:
There are many "human languages" (French, Japanese, English, Hindi etc)
There are many different "shell languages" (sh, csh, tcsh, zsh, bash etc)
Think of sh and bash as languages, not commands.
The errors you are getting is because your computer is expecting you to talk to it in sh, but actually you are talking to it in bash. It is like giving a French document to a German translator....
So, to resolve this, you just need to inform your computer that your script is written in bash.
To do this, simply add this line to the very top of your script file:
#!/bin/bash
Many Linux distributions use a smaller, simpler shell implementation than Bash for their default sh binary. They do this for various reasons. If you need Bash, run bash explicitly.
[[ is a Bash keyword similar to (but more powerful than) the [ command.
See
Bash FAQ 31
Test and Conditionals.
Unless you're writing for POSIX sh, it is recommended to use [[ instead of [.