简体   繁体   中英

Bash command works in terminal but not in script

I am trying to run a C executable(rtklib) with some parameters. The same command seems to work fine in terminal but when I run it in a sh file, the executable throws error.

bash script:

#!/bin/bash

# path to CUI executables
convbindir="/home/odroid/gitLibs/RTKLIB-master/app/convbin/gcc"
rnx2rtkpdir="/home/odroid/gitLibs/RTKLIB-master/app/rnx2rtkp/gcc"

datafiledir="/home/odroid/bashExample/datafiles"

basedir="$datafiledir/base*/"


cd $rnx2rtkpdir



# Do post process from each base to rover (should be 2)
for roverdir in $datafiledir/rover*/; do
    #echo "$roverdir" # absolute path to rover folder i.e. /home/odroid/bashExample/datafiles/rover2/ 
    #echo "basedir = $basedir" 

    rovernum="${roverdir: -2:-1}"
    #echo "$rovernum"   
    ls
    #echo "****************"
    echo "executing: $ ./rnx2rtkp -k optsEmlid.conf -o "$roverdir"rover"$rovernum".pos "$roverdir"*.obs "$basedir"*.obs "$basedir"*.nav"
    ./rnx2rtkp -k optsEmlid.conf -o "$roverdir"rover"$rovernum".pos "$roverdir"*.obs "$basedir"*.obs "$basedir"*.nav
    #echo "****************"
done

output (no nav datanav data error):

odroid@odroid:~/bashExample$ ./autopostprocess.sh 
ephemeris.o  makefile    opts4.conf  ppp_ar.o   rnx2rtkp    rtcm.o
geoid.o      options.o   optsEmlid.conf  ppp.o      rnx2rtkp.o  rtkcmn.o
gpsdata      opts1.conf  out.pos     preceph.o  rtcm2.o rtkpos.o
ionex.o      opts2.conf  pntpos.o    qzslex.o   rtcm3e.o    sbas.o
lambda.o     opts3.conf  postpos.o   rinex.o    rtcm3.o solution.o
executing: $ ./rnx2rtkp -k optsEmlid.conf -o /home/odroid/bashExample/datafiles/rover2/rover2.pos /home/odroid/bashExample/datafiles/rover2/*.obs /home/odroid/bashExample/datafiles/base*/*.obs /home/odroid/bashExample/datafiles/base*/*.nav
invalid option value pos1-snrmask (optsEmlid.conf:7)
no nav datanav data
ephemeris.o  makefile    opts4.conf      ppp_ar.o   rnx2rtkp    rtcm.o
geoid.o      options.o   optsEmlid.conf  ppp.o      rnx2rtkp.o  rtkcmn.o
gpsdata      opts1.conf  out.pos     preceph.o  rtcm2.o rtkpos.o
ionex.o      opts2.conf  pntpos.o    qzslex.o   rtcm3e.o    sbas.o
lambda.o     opts3.conf  postpos.o   rinex.o    rtcm3.o solution.o
executing: $ ./rnx2rtkp -k optsEmlid.conf -o /home/odroid/bashExample/datafiles/rover3/rover3.pos /home/odroid/bashExample/datafiles/rover3/*.obs /home/odroid/bashExample/datafiles/base*/*.obs /home/odroid/bashExample/datafiles/base*/*.nav
invalid option value pos1-snrmask (optsEmlid.conf:7)
no nav datanav data

executing on terminal manually(I ctr+c to quit early, note that i copy pasted the exact command i printed out in my script ie the text after executing: $)):

odroid@odroid:~/gitLibs/RTKLIB-master/app/rnx2rtkp/gcc$ ./rnx2rtkp -k optsEmlid.conf -o /home/odroid/bashExample/datafiles/rover2/rover2.pos /home/odroid/bashExample/datafiles/rover2/*.obs /home/odroid/bashExample/datafiles/base*/*.obs /home/odroid/bashExample/datafiles/base*/*.nav
invalid option value pos1-snrmask (optsEmlid.conf:7)
^Cocessing : 2018/01/03 21:05:47 Q=0
odroid@odroid:~/gitLibs/RTKLIB-master/app/rnx2rtkp/gcc$ 

The problem is that you're quoting $basedir when you execute the command, so it's not expanding the * wildcard, and looking for a directory literally named base* . Change to:

    ./rnx2rtkp -k optsEmlid.conf -o "$roverdir"rover"$rovernum".pos "$roverdir"*.obs $basedir*.obs $basedir*.nav

However, this is problematic because it won't work if any of the directories in $basedir have spaces in their names, since word splitting is also done.

The output of echo does not represent whether content is quoted, although quotes matter greatly in terms of how a command is interpreted.

The safe way to do this is to expand your glob into an array, and then validate the array's contents to check whether the glob expanded to exactly one item (as you expect it to). That may look something like the following:

shopt -s nullglob
base_inputs=( "$datafiledir"/base*/*.{obs,nav} )

for roverdir in "$datafiledir"/rover*/; do
  roverdir=${roverdir%/}; rovernum=${roverdir##*/rover}
  ./rnx2rtkp \
    -k optsEmlid.conf \
    -o "${roverdir}/rover${rovernum}.pos" \
    "$roverdir"/*.obs \
    "${base_inputs[@]}"
done

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM