3

I'm attempting to write a very simple script which calls an executable from a higher level folder. If I were just typing the command into the console, I would type

../filenamehere {options} {parameters}

When I try to do the same thing in a .sh file in order to run multiple processes at the same time, I attempt to write the following:

../filename {options} {parameters} &
../filename {options2} {parameters} &
../filename {options3} {parameters} &
../filename {options4} {parameters} &

Then, to run the file, I entered

chmod a+x script_file.sh
./script_file.sh

After which point I was given a "command not found" error 3 times. I assume this means that 1 of my 4 commands executed, but the other 3 didn't. If I type directly into the console exactly the same commands as I put in the .sh file, nothing goes wrong. What do I need to do to make this file run?

7
  • Also, this is my first experience with bash and scripting. I have little to no experience with this and the tutorial articles I am reading as I do this are not very helpful.
    – Teofrostus
    Oct 29, 2013 at 6:28
  • 1
    I should work. Please post the script and a directory listing (ls ..).
    – Matteo
    Oct 29, 2013 at 6:33
  • I don't see any problem calling/executing script located in one directory level up: $ cat a.ksh ../b.ksh echo done $ cat ../b.ksh echo inside b.ksh $ chmod a+x a.ksh ../b.ksh $ a.ksh inside b.ksh done You can try with absolute path while invoking also. What's the exact error?. And is this script from something like autosys job?, in which case it considers directory reference relative to autosys installed path Oct 29, 2013 at 6:45
  • I have no idea what autosys is, or what the $ cat command you're using is about. The exact error is ":command not found1:" and then ":command not found2:" and ":command not found3:"
    – Teofrostus
    Oct 29, 2013 at 7:01
  • Are you sure that writing such a narrow-purpose script (i.e., one that works only from a specific folder) is such good style? Shoudn't you perhaps aim at something larger? Oct 29, 2013 at 12:06

4 Answers 4

2

Are you using symlinks ?

To write reliable scripts, you should not be using "dirname $0". It relates to the $0 command, which is related to the calling command. If you are navigating across directories, use instead "readlink -f $0".

basedir="$(dirname $(readlink -f $0))"
$basedir/../filename {options} {parameters} &

readlink -f will give you the absolute path of your script, regardless of the link, workdir, etc...

1

You can try running your script with pwd before calling the executable to see if your script is changing the directory after running the first executable.

pwd
../filename {options} {parameters} &
pwd
../filename {options2} {parameters} &
pwd
../filename {options3} {parameters} &
pwd
../filename {options4} {parameters} &
5
  • Perhaps I'm just doing something horribly wrong. Including pwd in my .sh file, i get ": command not found 1: pwd", with a change in the line number for each pwd command...
    – Teofrostus
    Oct 30, 2013 at 22:01
  • can you post your script here?
    – VDR
    Oct 31, 2013 at 7:14
  • Here it is exactly: ../sim-outorder -fetch:ifqsize 1 -issue:width 1 -decode:width 1 -commit:width 1 cc1.alpha -O 1stmt.i > 1inst-cc1.std 2> 1inst-cc1.stat & ../sim-outorder -fetch:ifqsize 2 -issue:width 2 -decode:width 2 -commit:width 2 cc1.alpha -O 1stmt.i > 2inst-cc1.std 2> 2inst-cc1.stat & ../sim-outorder -fetch:ifqsize 4 -issue:width 4 -decode:width 4 -commit:width 4 cc1.alpha -O 1stmt.i > 4inst-cc1.std 2> 4inst-cc1.stat & ../sim-outorder -fetch:ifqsize 8 -issue:width 8 -decode:width 8 -commit:width 8 cc1.alpha -O 1stmt.i > 8inst-cc1.std 2> 8inst-cc1.stat &
    – Teofrostus
    Nov 2, 2013 at 2:03
  • For some reason, I can't make the lines show up separately... But each ../ is on it's own line. There's a total of 4 lines, with different parameters for the executable I'm running and different output file names. I know each of these commands works, as if I type the exact command into the console, I can get it to run. However, if I run the script (which I've named Part1-1.sh), I get 3 "command not found" errors, followed by the line numbers 1:, 2:, and 3:
    – Teofrostus
    Nov 2, 2013 at 2:06
  • You need to make sure $PATH is defined before your script runs. You can check this by running /usr/bin/env using it's full path at the beginning of your script.
    – Will
    May 11, 2015 at 2:00
0

It sounds like what you need to know is the current location of your script, regardless of how it's called (either with an absolute path, a relative path, or via the shell's $PATH). Once you know that, you can then reference your other executable via a path relative to the current location.

You can get the current location of the running script with the following:

MYLOC=`dirname $0`

...and then run your relative executable using this variable:

$MYLOC/../filename

This works regardless of the current working directory (e.g. $pwd) and even works if your script is found and executed via the shell's $PATH... since, if the script is executed via an absolute or relative path, $0 has the associated value... or, if the script is execute by searching the shell's $PATH, then $0 contains the absolute, full path to the script file.

2
  • So, I've now also tried just running the script with only the first command '../filename {options} {parameters} & Even in this case, I get ": command not found1:" Including the following at the top of my shell file: MYLOC ='dirname $0' $MYLOC/../filename {options} {parameters} I end up with the following error - "./Part1-1.sh: line 1: MYLOC: command not found : command not found2:" Perhaps I am misunderstanding what you mean?
    – Teofrostus
    Oct 30, 2013 at 21:58
  • Plese note: the dirname $0 is in backquotes not single-quotes. The use of the backquote character (the unshifted tilde on most keyboards) will cause the contents to be replaced with the output of the enclosing command. I believe its the same as $(command) but the backtick syntax is much older (and more general) Oct 31, 2013 at 23:20
-1

You probably change the current working directory when you are using ../filename. So, better is to use in your script_file.sh the following lines:

current_directory=$(pwd)
../filename {options} {parameters} &
cd $current_directory
../filename {options2} {parameters} &
cd $current_directory
../filename {options3} {parameters} &
cd $current_directory
../filename {options4} {parameters} &

This will give you for sure the expected result.

1
  • No, it does not work like that. Even if ../filename changes directory, it is a subprocess, so the parent does not feel the difference.
    – orion
    Jun 17, 2015 at 8:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.