This question already has answers here:
Bash: Syntax error: redirection unexpected
(9 answers)
Closed 8 years ago.
I have the following script:
#!/bin/sh
# Use the PhiPack software on our two aligned sets of sequences...
mkdir FcFeABC
cd FcFeABC
../bin/PhiPack/Phi -f ../../Data/Real_Sequences_and_Networks/FcFeABC_alignment.fas -o -v -w 10 -g
cd -
mkdir FcL10
cd FcL10
../bin/PhiPack/Phi -f ../../Data/Real_Sequences_and_Networks/FcL10_alignment.fas -o -v -w 10 -g
cd -
# Use the PhiPack software on the simulated Datasets...
cd ../Data/Simulated_Sequences_and_Networks/Constant_Sex/Theta\ =\ 0.066/Theta\ =\ 0.066/Medium/CutSequences/;
rmus=($(ls -d *.fas))
cd -
absfiles=(../Data/Simulated_Sequences_and_Networks/Constant_Sex/Theta\ =\ 0.066/Theta\ =\ 0.066/Medium/CutSequences/*.fas)
if [ ${#rmus[#]} = ${#absfiles[#]} ]
then
mkdir ${rmus[#]}
for ((i=0; i<${#absfiles[#]}; i++));
do
cd ${rmus[$i]}
.../bin/PhiPack/Phi -f ${absfiles[$i]} -o -v -w 10 -g
cd -
done
else
echo "Error, Number of files created and files to be read differs"
fi
Which hit's an error at line 16:
./runPhiTests.sh: 16: ./runPhiTests.sh: Syntax error: "(" unexpected
Which is this line:
rmus=($(ls -d *.fas))
I don't understand why the '(' is unexpected - it's a simple assignment of the results of ls to an array.
Thanks,
Ben W.
You aren't running it with bash. You are running with /bin/sh from your shebang line #!/bin/sh.
Either run with bash explicitly bash runPhiTests.sh or fix your shebang line #!/bin/bash.
Try to use #!/bin/bash instead of sh.
Related
This question already has answers here:
Difference between sh and Bash
(11 answers)
Closed 6 months ago.
I am getting bad substitution error on running the following shell script. (Line numbers written just for reference):
Line 11> SCENARIO_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
Line 12> SCENARIO_PATH="${SCENARIO_DIR}/scenarios"
The error in TeamCity is
| ./k6-run-all.sh: line 12: syntax error: bad substitution
Please note that on running this in local, I do not get this error and the scenario path is correctly extracted. But when I run this on TeamCity (which runs on Docker) it is giving me the above error.
Scenario path in my local is: /Users/sonaliagrawal/Documents/antman/src/scenarios/full-card-visa
Scenario path in TeamCity is extracting correctly despite the error which is:
//scenarios/full-card-visa
Solution tried:
Since in TeamCity, SCENARIO_DIR is itself just / hence I wrote an if then else to handle it, but it didn't help solve the substitution error, it just corrected the path to /scenarios/full-card-visa. The code I had added is as follows-
SCENARIO_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
echo "Scenario directory $SCENARIO_DIR"
SCENARIO_PATH=""
if [[ "$SCENARIO_DIR" = "/" ]]; then
SCENARIO_PATH="/scenarios"
else
SCENARIO_PATH="${SCENARIO_DIR}/scenarios"
fi
Reference:
In case it helps, Dockerfile is as follows:
FROM loadimpact/k6:0.34.1
COPY ./src/lib /lib
COPY ./src/scenarios /scenarios
COPY ./src/k6-run-all.sh /k6-run-all.sh
WORKDIR /
ENTRYPOINT []
CMD ["sh", "-c", "./k6-run-all.sh"]
It's because your script isn't being executed as a bash script. Put the following on the top of the .sh file.
#!/bin/bash
I am going through a setup script that I am attempting to understand; how the sed line works, in this instance. From my understanding, it is editing the src/conf-cc inline at the first line and appending -include /usr/include/errno.h/ to the last line of input? I have been referencing the sed manual to help me break this sed command down.
#!/usr/bin/env bash
# A script which installs daemontools
#
# Run as root!
#
if [ "$(id -u)" != "0" ]; then
echo "You must be root!" 1>&2
exit 1
fi
mkdir /package
chmod 1755 /package
cd /package
wget http://cr.yp.to/daemontools/daemontools-0.76.tar.gz
tar -xpf daemontools-0.76.tar.gz
rm -f daemontools-0.76.tar.gz
cd admin/daemontools-0.76
sed -i '1s/$/ -include \/usr\/include\/errno.h/' src/conf-cc
package/install
echo -e "start on runlevel [3] \nrespawn \nexec /command/svscanboot" >> /etc/init/svscan.conf
initctl reload-configuration
initctl start svscan
mkdir /var/svc.d
No, it just appends something to the first line. It's a substitution command:
addr s/pattern/replacement/
where addr is 1 (first line), pattern is $ (regex: end of line) and the replacement is the -include ... string. It's not really "replacing" anything as $ has zero width anyway.
Your misunderstanding is interpreting $ as an address instead of a regular expression.
This question already has answers here:
Are shell scripts sensitive to encoding and line endings?
(14 answers)
Closed last month.
I have a shell script that runs like this on my Ubuntu 12.04 LTS server:
cd /var/www/srv
But, for some reason, when I run it, it says: ./start.sh: 1: cd: can't cd to /var/www/srv
The directory exists, and it is run as root so no question of privileges. To add to the peculiarity, when I run the code in the terminal, it works.
This is a classic carriage return issue, caused by creating a shell script in a Windows/DOS editor.
Your problem:
$ cat start.sh
cd /
$ ./start.sh
cd: 1: can't cd to /
Your diagnosis:
$ cat -v start.sh
cd /^M
$ shellcheck start.sh
In start.sh line 1:
cd /
^-- SC1017: Literal carriage return. Run script through tr -d '\r' .
Your fix:
$ tr -d '\r' < start.sh > fixed.sh
$ chmod +x fixed.sh
$ ./fixed.sh
(no errors)
This question already has answers here:
Are shell scripts sensitive to encoding and line endings?
(14 answers)
Closed 3 years ago.
I am trying to run the below bash script in cygwin on windows 7
REPEATTIMES="$1"
if [ $# = 0 ]; then
echo "Usage: fetch topN repeatTimes"
exit 1
fi
for (( i=1; i<=$REPEATTIMES; i++ ))
do
echo "ITERATION: $i"
echo "GENERATING"
log=thelogs/log
bin/nutch generate crawl/segment -topN 10 > $log
batchId=`sed -n 's|.*batch id: \(.*\)|\1|p' < $log`
echo "batch id: $batchId "
# rename log file by appending the batch id
log2=$log$batchId
mv $log $log2
log=$log2
echo "FETCHING"
bin/nutch fetch crawl/segments/$batchId >> $log
echo "PARSING"
bin/nutch parse crawl/segments/$batchId >> $log
echo "UPDATING DB"
bin/nutch updatedb crawl/crawldb crawl/segments/$batchId >> $log
echo "Done "
done
But when i run it i get the error :
line 11 :syntax error near unexpected token '$'\r'
line 11 :'for (( i=1; i<= REPEATTIMES; i++ ))
The script works fine on a ubuntu server. But i need to run it now on a windows machine.
If you can't fix all your scripts, you should be able to modify the EOL behavior in Cygwin by setting an option to ignore CRs:
set -o igncr
If you add this to your .bash_profile, it will be globally set by default when you login:
export SHELLOPTS
set -o igncr
You can also do this per script internally by putting this line just after the #! line:
(set -o igncr) 2>/dev/null && set -o igncr; # this comment is required
You need the comment to ignore the CR in that line which is read before the option takes effect.
The latest version of Cygwin seems to only support files in Unix format (i.e. with \n for newlines as opposed to the DOS/Windows \r\n newline).
To fix this, run the /bin/dos2unix.exe utility, giving your script as the argument to the command:
e.g. /bin/dos2unix.exe myScript.sh
This will convert it to Unix format and you then should be able to run it.
I have a short bash script to get source code's dependency files.
#!/bin/sh
rule=$(cpp -P -w -undef -nostdinc -C -M file.cc)
rule=${rule##*:}
#echo $rule
echo ${rule//\\}
Unfortunately, it outputs ./findDep.sh: 5: ./findDep.sh: Bad substitution.
But if I uncomment echo $rule, the script will execute without any problem:
lib.h macro.inc fundamental.h lib/fs.h lib/net.h \ lib/net/fetch.h
lib.h macro.inc fundamental.h lib/fs.h lib/net.h lib/net/fetch.h
Any one know why?
Thanks in advance.
You should change #!/bin/sh to #!/bin/bash or #!/usr/bin/env bash.
I can't reproduce your problem here with Bash 4.2.29.
However, did you know that read will join lines with \ newline continuations by default?
read rule < <(cpp -P -w -undef -nostdinc -C -M file.cc)
echo "${rule##*:}"
Or, in a more sh-compatible way (I think),
cpp -P -w -undef -nostdinc -C -M file.cc | {
read rule
echo "${rule##*:}"
}