bash script error until [1: command not found - bash

Can someone solve my headache with the following code. I want to write a bash script that will create a table that contain interval of time according to informations input by a user and display table. this is a part of another program but I got stack with this until command that is supposed to be easy to use. Sorry! I'm coding in French but the idea is as I explained
#!/bin/bash
read -p "entrez l'heure de depart(exple: hh:mn:06 or hh:mn:36):" beg_time
read -p "entrez l'intervalle de temps en minute(exple: 10):" Inter
read -p "entrez le nombre d'occurence(exple: 4):" Nbre
let "i = 1"
let "Nb = $Nbre"
tab=("$beg_time")
until [ "$i" -eq "$Nb" ]
do
tab["$i"]=`date -j -v '+"$Inter"M' -f "%H:%M:%S" "$beg_time" "+%T"`
let "i += 1"
done
echo ${tab[*]}
but I'm get this as error
line 8: until [ 1: command not found
I need to mention that I'm using a MacOS so the date command may not work on other linux OS. Please help

fix the variable assignments:
i=1
Nb="${Nbre}"
the same goes for let "i += 1"

Launching this on my mac I don't have the same error :
+"$Inter"M: Cannot apply date adjustment
I think you don't need to quote in your until statement, it's two numbers.
Are you using bash or zsh ?

I find the problem with until. for some reasons I needed to add a space after ]. then I also needed to do some small changes to my script.
the final update is as following.
#!/bin/sh
read -p "entrez l'heure de depart(exple: hh:mn:06 or hh:mn:36):" beg_time
read -p "entrez l'intervalle de temps en minute(exple: 10):" Inter
read -p "entrez le nombre d'occurence(exple: 4):" Nbre
let "i = 1"
let "Nb = $Nbre"
tab=("$beg_time")
until [ $Nb -eq $i ]
do
tab["$i"]=`date -j -v ""+$Inter"M" -f "%H:%M:%S" "$beg_time" "+%T"`
beg_time=${tab["$i"]}
let "i += 1"
done
echo ${tab[*]}
thank you for helping

Related

Calculate number of days between 2 dates Unix Shell

I want to calculate number of days between two dates in the unix shell .
I tried to do a minus calculation but it dosen’t work .
This is my script
VAR1=$1
VAR2=$2
v_date_deb=`echo ${VAR1#*=}`
v_date_fin=`echo ${VAR2#*=}`
dif = ($v_date_deb - $v_date_fin)
echo dif
if [ "$v_date_deb" = "" ]
then
echo "Il faut saisir la date debut.."
exit
fi
if [ "$v_date_fin" = "" ]
then
echo "Il faut saisir la date fin.."
exit
fi
One attempt (but shot in the dark, since we don't know what is in your VAR1 variables)
ts1=$(date -d "${VAR1#*=}" +"%s")
ts2=$(date -d "${VAR2#*=}" +"%s")
dt=$(( (ts2 - ts1) / 86400 ))
Note the remark from William Pursell above: this solution is dependent on your "date" version. Date is not a built-in command from bash. And, particularly, the -d option (that allows to use the date specified instead of the current date that date is supposed to use otherwise, when used in "print the date" mode) is not common to all "date".

Script with multiline string and for loop

Writing a quick script for a temporary/repetitive task. Wrote a basic solution that works:
for thing in "$#";
do
/usr/mysql/bin/mysql -u xyz -p pdq <<END;
UPDATE table
SET table_atr = 'NW'
WHERE record_id = $thing
END
done
This works but forces a password check for every member of argument array (not ideal).
Tried to update it to this:
if {$# -le 1}; then
for thing in "$#";
do
/usr/mysql/bin/mysql -u xyz -p pdq <<END;
UPDATE table
SET table_atr = 'NW'
WHERE record_id = $thing
END
done
else
things = ""
for thing in "$#";
do
things += "$thing"
if {$thing == $#[$# - 1]}; then
things += "\n"
continue
else
things += ",\n"
done
/usr/mysql/bin/mysql -u xyz -p pdq <<END;
UPDATE table
SET table_atr = 'NW'
WHERE record_id IN
(
$things
)
END
TLDR: If there is more than one argument: do a for loop to fill a WHERE .. IN () statement. I realize this doesn't even need to be a multiline string and maybe that is my issue but the error I'm getting is (apparently) unrealted .
The error I get is:
line 24: syntax error near unexpected token' done'
line 24: ' done'
Neither I, nor my supervisor have much experience with shell scripts but I cannot see any syntax error with the 2nd for loop. Its exactly the same as the first which executes fine.
Any help is greatly appreciated, I may just have to go to the basic version or write this as a Perl script instead. Thanks!
Thanks everyone for all the advice. This was an edit that worked:
#!/bin/sh
if [ $# -le 1 ]; then
for thing in "$#";
do
/usr/mysql/bin/mysql -u xyz -p pdq <<END;
UPDATE table
SET table_atr = 'NW'
WHERE record_id = $thing
END
done
else
things=""
i=1
for thing in "$#";
do
things+="$thing"
if [ $i -eq $# ]; then
things+=""
else
things+=", "
fi
((i+=1))
done
/usr/mysql/bin/mysql -u xyz -p pdq <<END;
UPDATE table
SET table_atr = 'NW'
WHERE record_id IN ($things)
END
fi
There were indeed many syntax errors and changing the WHERE .. IN () string construction to a single line made this a lot easier. Luckily I didn't have to worry about inserting single quotes, mysql took the query without them.
I came out of this with a much higher respect for bash scripting. It is a serious language that requires its own study and I will approach it with much more attention to detail in the future.
Thanks again.

bash for script and input parameter

Can anyone help me to modify my script. Because it does not work. Here are three scripts.
1) pb.sh, use delphicpp_release software to read the 1brs.ab.sh and will give the output as 1brs.ab.out
2) 1brs.ab.sh, use for input parameter where a.sh(another script for protein structure), chramm.siz, charmm.crg are file for atom size and charge etc. rest of the parameters for run the delphicpp_release software.
3) a.sh, use for read several protein structures, which will be in the same directory.
my script_1 = pb.sh:
./delphicpp_release 1brs.ab.sh >1brs.ab.out
echo PB-Energy-AB = $(grep -oP '(?<=Energy> Corrected:).*' 1brs.ab.out) >>PB-energy.dat
cat PB-energy.dat
script_2 = 1brs.ab.sh:
in(pdb,file="a.sh")
in(siz,file="charmm.siz")
in(crg,file="charmm.crg")
perfil=70
scale=2.0
indi=4
exdi=80.0
prbrad=1.4
salt=0.15
bndcon=2
maxc=0.0001
linit=800
energy(s)
script_3 = a.sh:
for i in $(seq 90000 20 90040); do
$i.pdb
done
As we don't know what software is, something like
for ((i=90000;i<=100000;i+=20)); do
./software << " DATA_END" > 1brs.$i.a.out
scale=2.0
in(pdb,file="../$i.ab.pdb")
in(siz,file="charmm.siz")
in(crg,file="charmm.crg")
indi=z
exdi=x
prbrad=y
DATA_END
echo Energy-A = $(grep -oP '(?<=Energy>:).*' 1brs.$i.a.out) >>PB-energy.dat
done
A more POSIX shell compliant version
i=90000
while ((i<=100000)); do
...
((i+=20));
done
EDIT: Without heredoc
{
echo 'scale=2.0'
echo 'in(pdb,file="../'"$i"'.ab.pdb")'
echo 'in(siz,file="charmm.siz")'
echo 'in(crg,file="charmm.crg")'
echo 'indi=z'
echo 'exdi=x'
echo 'prbrad=y'
} > $i.ab.sh
./software <$i.ab.sh >$i.ab.out
but as question was changed I'm not sure to understand it.

Bash user prompt while reading file

I am trying to create a user prompt while reading a file a line by line in Bash. The idea is for me to plot various files one-by-one using Gnuplot. Here is what I have:
#!/bin/bash
echo "Enter filename that contains the filenames:"
read fname
xr="[1e8:1e20]"
yr="[1:1e13]"
while read line
do
echo -e "reset\nset log\nset xrange$xr\nset yrange$yr\nset xlabel \"Frequency [Hz]\"\nset ylabel \"F_{/Symbol n} [Jy Hz]\"\nset key top left\nplot \"$line.dat\" u 3:(\$3*\$4)*1e26 w l ti \"$line^o\" \n"> plt.gp
gnuplot plt.gp
done < $fname
I would like to enter a user input/"continue?" type thing before "gnuplot plt.gp" command, because at the moment it just plots everything rapidly and then exits. The standard read -p command does not work here. I read somewhere I may need to use file descriptor exec 5 command, but I don't understand. Thanks.
#!/bin/bash
read -p 'Enter filename that contains the filenames: ' fname
xr="[1e8:1e20]"
yr="[1:1e13]"
while read line
do
echo -e "reset\nset log\nset xrange$xr\nset yrange$yr\nset xlabel \"Frequency [Hz]\"\nset ylabel \"F_{/Symbol n} [Jy Hz]\"\nset key top left\nplot \"$line.dat\" u 3:(\$3*\$4)*1e26 w l ti \"$line^o\" \n"> plt.gp
gnuplot plt.gp
read -p 'Do you want to continue? [Y/n]: ' want_to_continue </dev/tty
case "${want_to_continue}" in
Y|y)
continue
;;
*)
echo "OK. Bye!"
break
;;
esac
done < ${fname}

Putting the output of a command with interaction inside a variable while using grep in bash

This program I use has it's own variables to set when you run it, so I want to set those variables and then greping the output then storing it inside a variable. However, I don't know how to go about this the correct way. The idea I have doesn't work. The focus is on lines 7 through 14.
1 #!/usr/local/bin/bash
2 source /home/gempak/NAWIPS/Gemenviron.profile
3 FILENAME="$(date -u '+%Y%m%d')_sao.gem"
4 SFFILE="$GEMDATA/surface/$FILENAME"
5 echo -n "Enter the station ID: "
6 read -e STATION
7 OUTPUT=$(sflist << EOF
8 SFFILE = $SFFILE
9 AREA = #$STATION
10 DATTIM = all
11 SFPARM = TMPF;DWPF
12 run
13 exit
14 EOF)
15 echo $OUTPUT
But I get this:
./listweather: line 7: unexpected EOF while looking for matching `)'
./listweather: line 16: syntax error: unexpected end of file
Putting together everyone's answers, I came across a working solution myself. This code works for me:
#!/usr/local/bin/bash
source /home/gempak/NAWIPS/Gemenviron.profile
FILENAME="$(date -u '+%Y%m%d')_sao.gem"
SFFILE="$GEMDATA/surface/$FILENAME"
echo -n "Enter the station ID: "
read -e STATION
OUTPUT=$(sflist << EOF
SFFILE = $SFFILE
AREA = #$STATION
DATTIM = ALL
SFPARM = TMPF;DWPF
run
exit
EOF
)
echo $OUTPUT | grep $STATION
Thanks everyone!
I'd put your program to run in a separate .sh script file, and then run the script from your first file, passing the arguments you want to pass as command line arguments. That way you can test them separately.
You could also do it in a function, but I like the modularity of the second script. I don't udnerstand exactly what you are trying to do above, but something like:
runsflist.sh:
#!/bin/bash
FILENAME="$(date -u '+%Y%m%d')_sao.gem"
SFFILE="$GEMDATA/surface/$FILENAME"
AREA = #$STATION
DATTIM = all
SFPARM = TMPF;DWPF
grep $STATION | sflist
main.sh:
#!/bin/bash
echo -n "Enter the station ID: "
read -e STATION
OUTPUT=`runsflist.sh`
echo $OUTPUT
If sflist needs interaction, I'd try something like this:
SFFILE=$(
( echo SFFILE = "$SFFILE"
echo AREA = "#$STATION"
echo DATTIM = all
echo SFPARM = TMPF;DWPF
echo run
cat
) | sflist)
Unfortunately, you have to type exit as part of the interaction.

Resources