I keep getting a 'bad substitution' error in my bash script at the point ${basename $option} where '$option' is input later in the script, does anyone know how to fix it?
function findByExtension {
strip=${basename $option}
extension="${strip##*.}"
}
I have also included '#!/bin/bash' at the start of the script.
You want to perform command substitution there, not parameter substitution.
strip="$(basename "$option")"
Related
our IT updated LSF farm/OS and now our Tcl script does not work anymore: within our script we executing "bsub -q reg -R "rh70" csh_file" in a loop.
for unknown reason, at some point during the loop 'on 5th element' we are getting following error message: "couldn't execute bsub" as if command is unkown...
we don't understand why starting at some point in the loop the same command does not work anymore... can you help me understand this issue?
Thanks,
Chris
sript is supposed to work without any issue within foreach loop (as it was the case before IT update LSF/OS).
I have a shell script that reads a text file and uses its content. So far so good. But now I'm trying to make the script exit if the file is not found. The script looks like this
#!/bin/bash
function errorcatcher() {
errorcode=$?
echo "ERROR CODE : ${errorcode}"
exit ${errorcode}
}
trap errorcatcher ERR
MYFILE=$1
IFS='|'
while read line; do
echo ${line}
done < ${MYFILE}
echo "Execution complete"
And I run the script as
sh myscript.sh /home/mydir/ABC.txt
and it works fine. But if I try this
sh myscript.sh /home/mydir/nonexisting.file
I get
myscript.sh: line 17: /home/mydir/nonexisting.file: No such file or directory
Execution complete
Function errorcatcher does not get invoked and instead of exiting with an error code, the execution continues and I get the line Execution complete even though the file in question doesn't exist. My guess is no error is generated here, so I added this line before reading the text file
ls ${MYFILE}
The errorcatcher gets invoked this time. But if I try
sh myscript.sh /home/mydir/ABC.tx
Instead of existing file ABC.txt, I pass its incomplete name ABC.tx and again, the errorcatcher function is not invoked and the script completes successfully (Execution complete gets echoed).
Could someone help me with this? I'm curious as to why errorcatcher doesn't get invoked
for a non existing file without ls
for incomplete file name (ABC.tx) with ls
Function errorcatcher does not get invoked …
Indeed, with an error in the redirection of a loop like
while read line; do
…
done < ${MYFILE}
the ERR trap is not invoked. You have discovered an undocumented exception in the implementation of the trap command, or, if you prefer, a bug.
You can evade that by adding an additional test of the redirection before the while, e. g. the line
<$MYFILE
on its own will invoke the error trap.
I am trying to access a string returned by a shell script which was called from a parent shell script. Something like this:
ex.sh:
echo "Hemanth"
ex2.sh:
sh ex.sh
if [ $? == "Hemanth" ]; then
echo "Hurray!!"
else
echo "Sorry Bro!"
fi
Is there a way to do this? Any help would be appreciated.
Thank you.
Use a command substitution syntax on ex2.sh
valueFromOtherScript="$(sh ex.sh)"
printf "%s\n" "$valueFromOtherScript"
echo by default outputs a new-line character after the string passed, if you don't need it in the above variable use printf as
printf "Hemanth"
on first script. Also worth adding $? will return only the exit code of the last executed command. Its values are interpreted as 0 being a successful run and a non-zero on failure. It will NEVER have a string value as you tried to use.
A Bash script does not really "return" a string. What you want to do is capture the output of a script (or external program, or function, they all act the same in this respect).
Command substitution is a common way to capture output.
captured_output="$(sh ex.sh)"
This initializes variable captured_output with the string containing all that is output by ex.sh. Well, not exactly all. Any script (or command, or function) actually has two output channels, usually called "standard out" (file descriptor number 1) and "standard error" (file descriptor number 2). When executing from a terminal, both typically end up on the screen. But they can be handled separately if needed.
For instance, if you want to capture really all output (including error messages), you would add a "redirection" after your command that tells the shell you want standard error to go to the same place as standard out.
captured_output="$(sh ex.sh 2>&1)"
If you omit that redirection, and the script outputs something on standard error, then this will still show on screen, and will not be captured.
Another way to capture output is sending it to a file, and then read back that file to a variable, like this :
sh ex.sh > output_file.log
captured_output="$(<output_file.log)"
A script (or external program, or function) does have something called a return code, which is an integer. By convention, a value of 0 means "success", and any other value indicates abnormal execution (but not necessarily failure) : the meaning of that return code is not standardized, it is ultimately specific to each script, program or function.
This return code is available in the $? special shell variable immediately after the execution terminates.
sh ex.sh
return_code=$?
echo "Return code is $return_code"
I'm trying to customize the ssh command in ubuntu using the ~/.bash_aliases file, basically I want to use the command 'zssh |$value|' to do: ssh root#name|$valuegoeshere|.hostname.org, I have tried to use this code:
function zssh{ssh root#name$1.hostname.org}
However I got the following error:
bash: /home/amirs/.bash_aliases: line 1: syntax error near unexpected
token root#name$1.hostname.org}' bash: /home/amirs/.bash_aliases:
line 1:function zssh{ssh root#name$1.hostname.org}'
Any suggestions on how to configure the following function?
The correct way to define a function is:
zssh () {
ssh root#name$1.hostname.org
}
The function keyword is optional and a bash extension, so there's no need to use it. You need whitespace around the { character, and there has to be a command delimiter (either newline or ;) before }.
I have a script which redirects std out/std err as below:
SCRIPTS=/test/scripts
LOG=/test/log
echo $SCRIPTS
echo $LOG
$SCRIPTS/dmm_algo_ofac_daily_sched.ksh >> $LOG/test12.log 2>&1
This script is not able to expand $SCRIPTS and $LOG
If I replace it as below:
/test/scripts/daily_sched.ksh >> /test/log/test12.log 2>&1
It complains as below:
: bad file unit numberd/test.ksh: line 33: 1
Also I am not able to invoke the script from the directory where it is saved. If I do
./test.ksh it gives me error saying file not found. I am able to execute it via ksh /test/sched/test.ksh though.
Can someone help me with these. Thanks in advance.
I'm almost certain that the problem is because of DOS/Windows line endings
The error message you are getting is overwriting itself because of a carriage return. You can fix your file using dos2unix.
Add magic #!/bin/ksh to the first line to invoke directly without naming the interpreter on the command line.
I'll conjecture wildly that your root cause(s) has (have) nothing to do with redirection.
Is the script you've exhibited /test/sched/test.ksh or /test/scripts/test.ksh? Are you certain?