error on last done preventing further processing in bash - bash

The below bash seems to error on the last done. What is the correct syntax as I can not seem to figure it out without created more errors. There are some additional processes after that will not run because an error is thrown currently. Thank you :).
error
/home/cmccabe/Desktop/loop.sh: line 79: syntax error near unexpected token `done'
/home/cmccabe/Desktop/loop.sh: line 79: `done >> "$logfile"'
bash
logfile=/home/cmccabe/Desktop/NGS/API/6-2-2016/process.log
for file in /home/cmccabe/Desktop/NGS/API/6-2-2016/vcf/overall/stats/*.vcf ; do
echo "Start annovar creation: $(date) - file: $file"
echo ${file##*/} >> /home/cmccabe/Desktop/NGS/annovar/target.txt
cp /home/cmccabe/Desktop/NGS/API/6-2-2016/vcf/overall/stats/*.vcf /home/cmccabe/Desktop/NGS/annovar
echo "End annovar file creation: $(date) - file: $file"
done
logfile=/home/cmccabe/Desktop/NGS/API/6-2-2016/process.log
cd "/home/cmccabe/Desktop/NGS/annovar"
$( perl -ne 'chomp; system ("perl table_annovar.pl -vcfinput $_ humandb/ -buildver hg19 -arg '-hgvs',,,,,,,,,, -remove -protocol IDP.refGene,avsnp147,popfreq_all_20150413,spidex,ljb26_sift,ljb26_pp2hdiv,ljb26_pp2hvar,ljb26_lrt,ljb26_mt,ljb26_ma,clinvar_20160302 -operation g,f,f,f,f,f,f,f,f,f,f")' < target.txt )
mv /home/cmccabe/Desktop/NGS/annovar/*multianno.txt /home/cmccabe/Desktop/NGS/API/6-2-2016/vcf/overall/annovar
echo "End annovar annotation creation: $(date) - file: $file"
done >> "$logfile"

You want the >> at the echo line, as such. The done is also redundant; there's no loop to close:
logfile=/home/cmccabe/Desktop/NGS/API/6-2-2016/process.log
cd "/home/cmccabe/Desktop/NGS/annovar"
$( perl -ne 'chomp; system ("perl table_annovar.pl -vcfinput $_ humandb/ -buildver hg19 -arg '-hgvs',,,,,,,,,, -remove -protocol IDP.refGene,avsnp147,popfreq_all_20150413,spidex,ljb26_sift,ljb26_pp2hdiv,ljb26_pp2hvar,ljb26_lrt,ljb26_mt,ljb26_ma,clinvar_20160302 -operation g,f,f,f,f,f,f,f,f,f,f")' < target.txt )
mv /home/cmccabe/Desktop/NGS/annovar/*multianno.txt /home/cmccabe/Desktop/NGS/API/6-2-2016/vcf/overall/annovar
# See here
echo "End annovar annotation creation: $(date) - file: $file" >> "$logfile"

Related

How to modify call stack in Bash?

Suppose I want to write a smart logging function log, that would read the line that is immediately after the log invocation and store it and its output in the log file. The function can find, read and execute the line of code that is in question. The problem is, that when the function returns, bash executes the line again.
Everything works fine except that assignment to BASH_LINENO[0] is silently discarded. Reading the http://wiki.bash-hackers.org/syntax/shellvars#bash_lineno I've learned that the variable is not read only.
function log()
{
BASH_LINENO[0]=$((${BASH_LINENO[0]}+1))
file=${BASH_SOURCE[1]##*/}
linenr=$((${BASH_LINENO[0]} + 1 ))
line=`sed "1,$((${linenr}-1)) d;${linenr} s/^ *//; q" $file`
if [ -f /tmp/tmp.txt ]; then
rm /tmp/tmp.txt
fi
exec 3>&1 4>&2 >>/tmp/tmp.txt 2>&1
set -x
eval $line
exitstatus=$?
set +x
exec 1>&3 2>&4 4>&- 3>&-
#Here goes the code that parses the /tmp/tmp.txt and stores it in the log
if [ "$exitstatus" -ne "0" ]; then
exit $exitstatus
fi
}
#Test case:
log
echo "Unfortunately this line gets appended twice" | tee -a bla.txt;
After consulting the wisdom of users on bug-bash#gnu.org mailing list it appears that modifying the call stack is not possible, after all. Here is an answer I got from Chet Ramey:
BASH_LINENO is a call stack; assignments to it should be (and are)
ignored. That's been the case since at least bash-3.2 (that's where I
quit looking).
There is an indirect way to force bash to not execute the next
command: set the extdebug option and have the DEBUG trap return a
non-zero status.
The above technique works very well for my purposes. I am finally able to do a production version of the log function.
#!/bin/bash
shopt -s extdebug
repetition_count=0
_ERR_HDR_FMT="%.8s %s#%s:%s:%s"
_ERR_MSG_FMT="[${_ERR_HDR_FMT}]%s \$ "
msg() {
printf "$_ERR_MSG_FMT" $(date +%T) $USER $HOSTNAME $PWD/${BASH_SOURCE[2]##*/} ${BASH_LINENO[1]}
echo ${#}
}
function rlog()
{
case $- in *x*) USE_X="-x";; *) USE_X=;; esac
set +x
if [ "${BASH_LINENO[0]}" -ne "$myline" ]; then
repetition_count=0
return 0;
fi
if [ "$repetition_count" -gt "0" ]; then
return -1;
fi
if [ -z "$log" ]; then
return 0
fi
file=${BASH_SOURCE[1]##*/}
line=`sed "1,$((${myline}-1)) d;${myline} s/^ *//; q" $file`
if [ -f /tmp/tmp.txt ]; then
rm /tmp/tmp.txt
fi
echo "$line" > /tmp/tmp2.txt
mymsg=`msg`
exec 3>&1 4>&2 >>/tmp/tmp.txt 2>&1
set -x
source /tmp/tmp2.txt
exitstatus=$?
set +x
exec 1>&3 2>&4 4>&- 3>&-
repetition_count=1 #This flag is to prevent multiple execution of the current line of code. This condition gets checked at the beginning of the function
frstline=`sed '1q' /tmp/tmp.txt`
[[ "$frstline" =~ ^(\++)[^+].*$ ]]
# echo "BASH_REMATCH[1]=${BASH_REMATCH[1]}"
eval 'tmp="${BASH_REMATCH[1]}"'
pluscnt=$(( (${#tmp} + 1) *2 ))
pluses="\+\+\+\+\+\+\+\+\+\+\+\+\+\+\+\+\+\+\+\+\+\+\+\+\+\+\+\+"
pluses=${pluses:0:$pluscnt}
commandlines="`awk \" gsub(/^${pluses}\\s/,\\\"\\\")\" /tmp/tmp.txt`"
n=0
#There might me more then 1 command in the debugged line. The next loop appends each command to the log.
while read -r line; do
if [ "$n" -ne "0" ]; then
echo "+ $line" >>$log
else
echo "${mymsg}$line" >>$log
n=1
fi
done <<< "$commandlines"
#Next line extracts all lines that are prefixed by sufficent number of "+" (usually 3), that are immidiately after the last line prefixed with $pluses, i.e. after the last command line.
awk "BEGIN {flag=0} /${pluses}/ { flag=1 } /^[^+]/ { if (flag==1) print \$0; }" /tmp/tmp.txt | tee -a $log
if [ "$exitstatus" -ne "0" ]; then
echo "## Exit status: $exitstatus" >>$log
fi
echo >>$log
if [ "$exitstatus" -ne "0" ]; then
exit $exitstatus
fi
if [ -n "$USE_X" ]; then
set -x
fi
return -1
}
log_next_line='eval if [ -n "$log" ]; then myline=$(($LINENO+1)); trap "rlog" DEBUG; fi;'
logoff='trap - DEBUG'
The usage of the file is intended as follows:
#!/bin/bash
log=mylog.log
if [ -f mylog.log ]; then
rm mylog.log
fi
. ./log.sh
a=example
x=a
$log_next_line
echo "KUKU!"
$log_next_line
echo $x
$log_next_line
echo ${!x}
$log_next_line
echo ${!x} > /dev/null
$log_next_line
echo "Proba">/tmp/mtmp.txt
$log_next_line
touch ${!x}.txt
$log_next_line
if [ $(( ${#a} + 6 )) -gt 10 ]; then echo "Too long string"; fi
$log_next_line
echo "\$a and \$x">/dev/null
$log_next_line
echo $x
$log_next_line
ls -l
$log_next_line
mkdir /ddad/adad/dad #Generates an error
The output (`mylog.log):
[13:39:51 adam#adam-N56VZ:/home/Adama-docs/Adam/Adam/linux/tmp/log/log-test-case.sh:14] $ echo 'KUKU!'
KUKU!
[13:39:51 adam#adam-N56VZ:/home/Adama-docs/Adam/Adam/linux/tmp/log/log-test-case.sh:16] $ echo a
a
[13:39:51 adam#adam-N56VZ:/home/Adama-docs/Adam/Adam/linux/tmp/log/log-test-case.sh:18] $ echo example
example
[13:39:51 adam#adam-N56VZ:/home/Adama-docs/Adam/Adam/linux/tmp/log/log-test-case.sh:20] $ echo example
[13:39:51 adam#adam-N56VZ:/home/Adama-docs/Adam/Adam/linux/tmp/log/log-test-case.sh:22] $ echo 1,2,3
[13:39:51 adam#adam-N56VZ:/home/Adama-docs/Adam/Adam/linux/tmp/log/log-test-case.sh:24] $ touch example.txt
[13:39:51 adam#adam-N56VZ:/home/Adama-docs/Adam/Adam/linux/tmp/log/log-test-case.sh:26] $ '[' 13 -gt 10 ']'
+ echo 'Too long string'
Too long string
[13:39:51 adam#adam-N56VZ:/home/Adama-docs/Adam/Adam/linux/tmp/log/log-test-case.sh:28] $ echo '$a and $x'
[13:39:51 adam#adam-N56VZ:/home/Adama-docs/Adam/Adam/linux/tmp/log/log-test-case.sh:30] $ echo a
a
[13:39:51 adam#adam-N56VZ:/home/Adama-docs/Adam/Adam/linux/tmp/log/log-test-case.sh:32] $ ls -l
total 12
-rw-rw-r-- 1 adam adam 0 gru 4 13:39 example.txt
lrwxrwxrwx 1 adam adam 66 gru 4 13:29 log.sh -> /home/Adama-docs/Adam/Adam/MyDocs/praca/Puppet/bootstrap/common.sh
-rwxrwxr-x 1 adam adam 520 gru 4 13:29 log-test-case.sh
-rw-rw-r-- 1 adam adam 995 gru 4 13:39 mylog.log
[13:39:51 adam#adam-N56VZ:/home/Adama-docs/Adam/Adam/linux/tmp/log/log-test-case.sh:34] $ mkdir /ddad/adad/dad
mkdir: cannot create directory ‘/ddad/adad/dad’: No such file or directory
## Exit status: 1
The standard output is unchanged.
Limitations
Limitations are serious, unfortunately.
Exit code of logged command gets discarded
First of all, the exit code of the logged command is discarded, so user cannot test for it in the next statement. The current code exits the script if there was an error (which I believe is the best behavior). It is possible to modify the script to test
Limited support for bash tracing
The function honors bash tracing with -x. If it finds that the user traces output, it temporarily disables the output (as it would interfere with the trace anyway), and restores it back at the end. Unfortunately, it also appends a few extra lines to the trace.
Unless user turns off logging (with $logoff) there is a considerable speed penalty for all commands after the first $log_next_line, even if no logging takes place.
In ideal world the function should disable debug trapping (trap - DEBUG) after each invocation. Unfortunately I don't know how to do it, so beginning with the first $log_next_line macro, interpretation of each line invokes a custom function.
I use this function before every key command in my complex bootstrapping scripts. With it I can see what exactly and when was executed and what was the output, without the need to really understand the logic of the lengthy and sometimes messy scripts.

shell script variable scope after cd

Why after call cd command on below script, the second echo line don't work?
#!/bin/bash
LOGFILE='my.log'
echo 'log line 1' >> $LOGFILE
cd folder-x
echo 'log line 2' >> $LOGFILE
And without cd command it's work?
#!/bin/bash
LOGFILE='my.log'
echo 'log line 1' >> $LOGFILE
#cd folder-x
echo 'log line 2' >> $LOGFILE
LOGFILE isn't a file variable, it's just a file name. Not even that, it's just text.
So what happens is:
echo 'log line 1' >> $LOGFILE
writes in to my.log in the current directory, because this translates to:
echo 'log line 1' >> my.log
then we
cd folder-x
and
echo 'log line 2' >> $LOGFILE
expands to:
echo 'log line 2' >> my.log
which is just what happens - in the new current directory.
You could include the current directory in LOGFILE, so future log statements are appended there, like so:
#!/bin/bash
LOGFILE="`pwd`/my.log"
echo 'log line 1' >> $LOGFILE
cd folder-x
echo 'log line 2' >> $LOGFILE
It will create two log files. One from where you are running script. Another in folder-x.

Check if file exists [BASH]

How do I check if file exists in bash?
When I try to do it like this:
FILE1="${#:$OPTIND:1}"
if [ ! -e "$FILE1" ]
then
echo "requested file doesn't exist" >&2
exit 1
elif
<more code follows>
I always get following output:
requested file doesn't exist
The program is used like this:
script.sh [-g] [-p] [-r FUNCTION_ID|-d FUNCTION_ID] FILE
Any ideas please?
I will be glad for any help.
P.S. I wish I could show the entire file without the risk of being fired from school for having a duplicate. If there is a private method of communication I will happily oblige.
My mistake. Fas forcing a binary file into a wrong place. Thanks for everyone's help.
Little trick to debugging problems like this. Add these lines to the top of your script:
export PS4="\$LINENO: "
set -xv
The set -xv will print out each line before it is executed, and then the line once the shell interpolates variables, etc. The $PS4 is the prompt used by set -xv. This will print the line number of the shell script as it executes. You'll be able to follow what is going on and where you may have problems.
Here's an example of a test script:
#! /bin/bash
export PS4="\$LINENO: "
set -xv
FILE1="${#:$OPTIND:1}" # Line 6
if [ ! -e "$FILE1" ] # Line 7
then
echo "requested file doesn't exist" >&2
exit 1
else
echo "Found File $FILE1" # Line 12
fi
And here's what I get when I run it:
$ ./test.sh .profile
FILE1="${#:$OPTIND:1}"
6: FILE1=.profile
if [ ! -e "$FILE1" ]
then
echo "requested file doesn't exist" >&2
exit 1
else
echo "Found File $FILE1"
fi
7: [ ! -e .profile ]
12: echo 'Found File .profile'
Found File .profile
Here, I can see that I set $FILE1 to .profile, and that my script understood that ${#:$OPTIND:1}. The best thing about this is that it works on all shells down to the original Bourne shell. That means if you aren't running Bash as you think you might be, you'll see where your script is failing, and maybe fix the issue.
I suspect you might not be running your script in Bash. Did you put #! /bin/bash on the top?
script.sh [-g] [-p] [-r FUNCTION_ID|-d FUNCTION_ID] FILE
You may want to use getopts to parse your parameters:
#! /bin/bash
USAGE=" Usage:
script.sh [-g] [-p] [-r FUNCTION_ID|-d FUNCTION_ID] FILE
"
while getopts gpr:d: option
do
case $option in
g) g_opt=1;;
p) p_opt=1;;
r) rfunction_id="$OPTARG";;
d) dfunction_id="$OPTARG";;
[?])
echo "Invalid Usage" 1>&2
echo "$USAGE" 1>&2
exit 2
;;
esac
done
if [[ -n $rfunction_id && -n $dfunction_id ]]
then
echo "Invalid Usage: You can't specify both -r and -d" 1>&2
echo "$USAGE" >2&
exit 2
fi
shift $(($OPTIND - 1))
[[ -n $g_opt ]] && echo "-g was set"
[[ -n $p_opt ]] && echo "-p was set"
[[ -n $rfunction_id ]] && echo "-r was set to $rfunction_id"
[[ -n $dfunction_id ]] && echo "-d was set to $dfunction_id"
[[ -n $1 ]] && echo "File is $1"
To (recap) and add to #DavidW.'s excellent answer:
Check the shebang line (first line) of your script to ensure that it's executed by bash: is it #!/bin/bash or #!/usr/bin/env bash?
Inspect your script file for hidden control characters (such as \r) that can result in unexpected behavior; run cat -v scriptFile | fgrep ^ - it should produce NO output; if the file does contain \r chars., they would show as ^M.
To remove the \r instances (more accurately, to convert Windows-style \r\n newline sequences to Unix \n-only sequences), you can use dos2unix file to convert in place; if you don't have this utility, you can use sed 's/'$'\r''$//' file > outfile (CAVEAT: use a DIFFERENT output file, otherwise you'll destroy your input file); to remove all \r instances (even if not followed by \n), use tr -d '\r' < file > outfile (CAVEAT: use a DIFFERENT output file, otherwise you'll destroy your input file).
In addition to #DavidW.'s great debugging technique, you can add the following to visually inspect all arguments passed to your script:
i=0; for a; do echo "\$$((i+=1))=[$a]"; done
(The purpose of enclosing the value in [...] (for example), is to see the exact boundaries of the values.)
This will yield something like:
$1=[-g]
$2=[input.txt]
...
Note, though, that nothing at all is printed if no arguments were passed.
Try to print FILE1 to see if it has the value you want, if it is not the problem, here is a simple script (site below):
#!/bin/bash
file="${#:$OPTIND:1}"
if [ -f "$file" ]
then
echo "$file found."
else
echo "$file not found."
fi
http://www.cyberciti.biz/faq/unix-linux-test-existence-of-file-in-bash/
Instead of plucking an item out of "$#" in a tricky way, why don't you shift off the args you've processed with getopts:
while getopts ...
done
shift $(( OPTIND - 1 ))
FILE1=$1

bash script prova.sh: line 76: syntax error: unexpected end of file

I have below script but I can't find the error. Somebody an help me ?
In concrete I split a big file in different then compress any file, move it and send by ftp rename destination filename.
Something not work :(
in line:
put ${file} ${7}.T${j}(+1)
I try to rename the file with (+1) ended new filename
Kind regards
#!/bin/bash
# configuration stuff
# ${1} absolute path file
# ${2} num_files
# ${3} output_filename
# ${4} ipMainframe ip to put files
# ${5} FTP username
# ${6} FTP password
# ${7} destination filename
if [ ! $# == 7 ]; then
#number of parameter different of two
echo "Number of parameter incorrect"
echo "Command use: LLP_split_gzip_sendFTPandTrigger.sh absolute_path_file number_of_pieces output_filename ipMainframe userFTP pwdFTP destinationFilename"
exit 1
fi
if [ -f ${1} ]; then
# If file exists
if [[ ${2} =~ ^[\-0-9]+$ ]] && (( ${2} > 0)); then
# if number of pieces is an integer > 0
#Remove old files
echo "home directory = $HOME"
CMD=`rm -f '"$HOME"/"$3"*'`
if [ $? != 0 ]; then
echo "Impossible to remove old files $home/llp_tmp* $home/"$3"* in home directory"
echo $CMD
fi
# Calculate line for every file splitted
total_lines=$(cat ${1} | wc -l)
((lines_per_file = (total_lines + ${2} - 1) / ${2}))
# Split the actual file, maintaining lines.
CMD=`split -l "$lines_per_file" "$1" "$HOME"/llp_tmp`
if [ $? != 0 ]; then
echo "SPLITTING FILE ERROR: problem to split file."
echo $CMD
exit 3
fi
#For every file splitted rename and zip it
i=1
for file in $HOME/llp_tmp*; do
CMD=`mv "$file" "$3"."$i"`
if [ $? != 0 ]; then
echo "Impossible to rename file"
echo $CMD
exit 5
fi
CMD=`gzip "$3"."$i"`
if [ $? != 0 ]; then
echo "Impossible to compress file $3.$i"
echo $CMD
exit 6
fi
i=`expr $i + 1`
done
ftp -n ${4} << EOF
j=1
user ${5} ${6}
for file in $3.*; do
put ${file} ${7}.T${j}(+1)
j=`expr $j + 1`
done
quit
else
echo "number of pieces second parameter must be more than 0."
exit 2
fi
else
echo "absolute path first paramater doesnt exist"
exit 1
fi
exit 0
You are not terminating your here document. When I run your script I get:
gash.sh: line 72: warning: here-document at line 54 delimited by end-of-file (wanted `EOF')
gash.sh: line 73: syntax error: unexpected end of file
ftp -n ${4} << EOF is the issue. Where is your here document?
The warning says it all, you don't have an EOF marker. Note that this MUST NOT BE INDENTED! The EOF must be in "column 0" and have no trailing characters, including whitespace.
Edit: It appears you want to use program constructs within a single FTP session - I don't know of a way of doing that in Bash. Perl has an easy to use FTP module where you can do it, simple example:
use strict;
use Net::FTP;
my $ftp = Net::FTP->new ("hostname");
$ftp->login ("username", "password");
$ftp->binary ();
for my $file (glob("$ENV{HOME}/llp_tmp*")) {
$ftp->put ($file);
}
$ftp->quit();
You don't need parentheses around +1.
Change it to:
put "${file}" "${7}.T${j}+1"
It's good practice to quote variables.
Another tip: Instead of j=`expr $j + 1`, you can simply use ((j++)).

multiple sed operations creating empty file

When as part of shell script only one line is operating on a file using sed command the redirected file contains the updated data, as below
cat ${PROP_PATH}/${PROP_FILE} | sed "s!${ISTR_KEY}=.*!${ISTR_KEY}=${SIM_ISTR_KEY_VAL}!" > ${UPDATEDPROPS_DIR}/${PROP_FILE}
whereas when it is executed as part of a shell script, where after this another sed command updates the same file as in the below script at the end what i get is an empty file, why ? ..... ideas please.
(check 'switchAll2Sim()' function below)
#!/bin/ksh
#
SIM_ICR_KEY_VAL="http://www.example.com/sim/http/icr"
SIM_ISTR_KEY_VAL="http://www.example.com/sim/http/istr"
SIM_GT_KEY_VAL="http://www.example.com/sim/http/gtr"
#
ICR_KEY="interface.url.icr"
ISTR_KEY="interface.url.istr"
GT_KEY="interface.ws.url.gt"
## Property Files
PROP_PATH=""
PROP_FILE="properties"
##
DATE=`date +%m%d%Y`
DATETIME=`date +%m%d%Y-%T`
BCKUP_DIR=_bckup
UPDATEDPROPS_DIR=_updatedprops
# ----------------------------------
pause(){
echo "Press [Enter] key to continue..."
read fackEnterKey
}
permissions(){
chmod 777 ${UPDATEDPROPS_DIR}
}
backup(){
if [ ! -d "${BCKUP_DIR}" ]; then
mkdir ${BCKUP_DIR}
fi
if [ ! -d "${UPDATEDPROPS_DIR}" ]; then
mkdir ${UPDATEDPROPS_DIR}
fi
permissions
## keep backup of properties
cp ${PROP_PATH}/${PROP_FILE} ${BCKUP_DIR}/${PROP_FILE}_${DATETIME}
echo "Backup of property files completed at: " ${DATETIME}
}
#-------------------------------------------------------------
# switch all properties to SIM
#-------------------------------------------------------------
switchAll2Sim(){
backup
#
# update files
cat ${PROP_PATH}/${PROP_FILE} | sed "s!${ISTR_KEY}=.*!${ISTR_KEY}=${SIM_ISTR_KEY_VAL}!" > ${UPDATEDPROPS_DIR}/${PROP_FILE}
cat ${UPDATEDPROPS_DIR}/${PROP_FILE} | sed "s!${ICR_KEY}=.*!${ICR_KEY}=${SIM_ICR_KEY_VAL}!" > ${UPDATEDPROPS_DIR}/${PROP_FILE}
cat ${UPDATEDPROPS_DIR}/${PROP_FILE} | sed "s!${GT_KEY}=.*!${GT_KEY}=${SIM_GT_KEY_VAL}!" > ${UPDATEDPROPS_DIR}/${PROP_FILE}
echo "Switch all to SIM completed at: " ${DATETIME}
pause
}
# switch all properties to real
#-------------------------------------------------------------
switchAll2Real(){
pause
}
#-------------------------------------------------------------
dispCurrentStats(){
echo "Displaying current properties..."
echo "*********************************"
echo " File: " ${PROP_PATH}/${PROP_FILE}
grep ${ICR_KEY} ${PROP_PATH}/${PROP_FILE}
grep ${ISTR_KEY} ${PROP_PATH}/${PROP_FILE}
grep ${GT_KEY} ${PROP_PATH}/${PROP_FILE}
#
echo "*********************************"
pause
}
show_menus() {
clear
echo "~~~~~~~~~~~~~~~~~~~~~"
echo " M E N U"
echo "~~~~~~~~~~~~~~~~~~~~~"
echo "1. Display current properties"
echo "2. Switch all to real"
echo "3. Switch all to simulator"
echo "4. Exit"
}
# read input from the keyboard and take a action
read_options(){
read option
case $option in
1) dispCurrentStats ;;
2) switchAll2Real ;;
3) switchAll2Sim ;;
4) exit 0;;
*) echo "Please insert options 1 ~ 4";;
esac
}
# -----------------------------------
# Main - infinite loop
# ------------------------------------
while true
do
show_menus
read_options
done
Thanks, using '-i, says [sed: illegal option -- i]
Then you have to work with tmp files.
cp foo foo.tmp
sed "s/x/y/" foo.tmp > foo
/bin/rm foo.tmp
OR
sed "s/x/y/" foo > foo.tmp
/bin/mv -f foo.tmp foo
is probably more efficient.
I hope this helps.
Your problem is that cat is reading from the same file that sed is writing to.
cat foo | sed "s/x/y/" > foo
Will not work because cat and sed run at the same time, not one after the other.
To fix this try the -i option to sed.
sed -i "s/x/y/" foo

Resources