Syntax Error in bash while loop - bash

What is the error in that?
j=0
filenames=("")
filedates=("")
while read line
do
filenames[$j]="$line"
filedates[$j]=$(stat -c %y ${filenames[$j]} | cut -d ' ' -f1)
(( j++ ))
done < <(ls -t *.gz)
Out:
script.sh: line 9: syntax error near unexpected token `<'
script.sh: line 9: `done < <(ls -t *.gz)'
Really i don't know the error in that while loop, i tested it on several machine but same problem

The problem is that you're using bash specific <(process substition), but running your script with /bin/sh.
Use bash script.sh instead of sh script.sh, and make sure the shebang uses bash and not sh.

use a for loop
for file in *t.gz
do
...
done

Related

simple 'printf' in bash gets screwed up output

I'm a newbie here. I've really tried to google it but failed.
I've got a simple script that reads from file line by line and then prints it. "b.txt" has the first line of "02083192846".
#!/bin/bash
while IFS= read -r line; do
printf 'downloading %s .html\n' $line
done < "$1"
however, the output is screwed up:
User#User-pk ~/test
$ ./test.sh b.txt
.htmlading 02083192846
Once this is fixed, my next question is how to use this line as part of the file name that some command will store into. i.e. the filename should be "02083192846.html". I've tried setting using it as ${line}.html but it doesn't work. For example grep "foo" -f ${line}.html doesn't work. But curl http://foo -o $line.html does work still!
What I would do :
#!/bin/bash
while IFS= read -r line; do
printf 'downloading %s .html\n' "${line//$'\r'/}"
#  ________
done < "$1"
#  ^
# remove \r with bash parameter expansion

Using while loop without process substitution, while allowing global variable value modification inside the loop

I have a script that when I run from a file manager (Filza), it return an error saying
command substitution: syntax error near unexpected token `('.
line 56: `paste -d'\n' <(echo "$var1") <(echo "$var2"))'
But when I run it from a terminal (./myscript.sh), it ran with no error. Here's the code that gave the error:
#!/bin/bash
var1="A
B
C"
var2="1
2
3"
globalvar=0
while read v1 && read v2; do
globalvar=$(echo $v1 $v2)
done<<<$(paste -d'\n' <(echo "$var1") <(echo "$var2"))
As commented below, it's probably some shell doesn't allow process substitution, thus why it failed. This command is running on iOS environment (jailbroken). Is there alternative way to implement this? Thanks in advance!
Try using 'here document' (<<) instead of 'here string' (<<<). It is supported by most shells.
while read v1 && read v2; do
globalvar=$(echo $v1 $v2)
done <<__END__
$(paste -d'\n' <(echo "$var1") <(echo "$var2"))
__END__
The other option is create a shell wrapper that will force bash (from the question, looks like bash is installed and working). Rename original script to script-run, and modify the shell script to call the script-run
#! /bin/sh
exec /bin/bash ${0%/*}/script-run "$#"
Or other equivalent.

Removing character from variable in BASH script

I have a script which utilises SaltStack's command-line as well as BASH commands. The script is used to gather data from multiple Linux servers (hence SaltStack), one of the checks which I would like to gather is disk space.
I have done this by using the following command:
salt $i cmd.run 'df -Ph / | tail -n1 | awk '"'"'{ print $4}'"'"'' | grep -v $i
$i = hostname and the use of the ugly '"'"' is so that my command can run via SaltStack as Salt's remote execution functionality requires single quotes around the command, if I left them in my command wouldn't run inside my BASH script.
Example syntax:
salt $hostname cmd.run 'command here'
After many questions on here and with colleagues I have this section of the script sorted. However I now the problem of stripping the output of my above command to remove the 'G' so that my script can compare the output with a threshold I have defined and turn the HTML which this script is piping to red.
Threshold:
diskspace_threshold=5
Command:
while read i ; do
diskspace=`salt $i cmd.run 'df -Ph / | tail -n1 | awk '"'"'{ print $4}'"'"'' | grep -v $i`
Validation check:
if [[ "${diskspace//G}" -lt $diskspace_threshold ]]; then
ckbgc="red"
fi
The method I have used for stripping the G works on the command line but not within my script so it must be something to do with the syntax or just the fact that it is now within a script. Any ideas/thoughts would be helpful.
Cheers!
EDIT: Here is the error message I receive when running my script:
serverdetails.sh: line 36: p
: 2.8: syntax error: invalid arithmetic operator (error token is ".8")
I assume the error is coming from here (is this line 36?)
if [[ "${diskspace//G}" -lt $diskspace_threshold ]]; then
Note the error message:
serverdetails.sh: line 36: p : 2.8: syntax error: invalid arithmetic operator (error token is ".8")
bash does not do floating point arithmetic
$ [[ 2.8 -lt 3 ]] && echo OK
bash: [[: 2.8: syntax error: invalid arithmetic operator (error token is ".8")
You'll need to do something like this:
result=$( bc <<< "${diskspace%G} < $diskspace_threshold" )
if [[ $result == 1 ]]; then
echo OK
else
echo Boo
fi

"syntax error near expected token" using process substition

It's a bit of embarrassing question but i can not found the error. I am trying to do process substitution. Here is my code
while read compareFile1 <&3 && read compareFile2 <&4; do
echo compareFile1
echo compareFile2
done 3< <(tail -n+4 test2.txt) 4< <(tail -n+4 test2.txt)
but the error is,
sh.sh: line 7: syntax error near unexpected token `<'
sh.sh: line 7: `done 3< <(tail -n+4 test2.txt) 4< <(tail -n+4 test2.txt)
Any can help?
Process substitution is not an available feature in POSIX sh (#!/bin/sh, also invoked with sh yourscript); despite tagging this question "bash", you're clearly executing your script with a non-bash shell (or are otherwise entering portability mode, as with set -o posix).
Use bash instead; thus, putting #!/bin/bash at the beginning of your script, or invoking it with bash yourscript if specifying an interpreter manually.

Syntax error in shell script saying unexpected token `(

I have written the following shell script
while :; do
status=$($EMR_BIN/elastic-mapreduce --jobflow $JOBFLOW --list | grep "CopyLogs" | awk '{print $1}')
[[ $status == +( *RUNNING*|*PENDING*|*WAITING* ) ]] || break
sleep 60
done
Its giving me an error in line 3 saying syntax error in conditional expression: unexpected token('' . I tried giving whitespaces between my braces, but its not working.
Can anyone help me out.
Looks like you are trying to use extended globbing. Make sure you have shopt -s extglob somewhere earlier in your script, or rewrite to use standard globbing.
#!/bin/sh
while :; do
case $($EMR_BIN/elastic-mapreduce --jobflow $JOBFLOW --list | awk '/CopyLogs/{print $1}') in
*RUNNING*|*PENDING*|*WAITING* ) sleep 60;;
*) break;;
esac
done
Since there are no remaining Bashisms, this script is now POSIX sh compatible. (Personally, I also think it is more readable this way.)
(Note also the fix for the useless grep | awk.)

Resources