4

i have a small script that runs a jar file :

#!/bin/bash

prefix="foo";
name=`ls ${prefix}*.jar`;
echo $name;
java -jar $name prop1.properties prop2.properties

when i run it in the terminal using ./myscript.sh, it works fine and the jar file executes, but when i rename it in myscript.command and double click it, i have this error :

ls: foo*.jar : No such file or directory

I saw that apparently a .command file opens a terminal at the root directory, so I tried finding the directory containing myscript.command using that :

dir = 'find <dir> -maxdepth 1 -type d -name '*myDirContainingJar*' -print -quit'
cd $dir

but dir is just blank, any ideas ???

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
Sech
  • 177
  • 1
  • 5
  • 18
  • 1
    The `dir = ...` command won't work for 3 reasons: 1) The spaces around the `=` mean the shell won't treat it as an assignment (it's treated as the `dir` command, with `=` as its first argument). 2) The single-quotes around the `find` command mean it'll be treated as a string rather than a command; you want backquotes or `$( )` (with `$( )` being the preferred option). And 3) there may be more than one directory matching the pattern, and it won't reliably pick the right one. – Gordon Davisson Jul 07 '17 at 16:37

2 Answers2

8

Opening a shell script from Finder on macOS (whether it has extension .command or is an extension-less executable shell script) makes the current user's home directory the current directory (as of macOS 10.12).

To explicitly change to the directory in which the script itself is located in a bash script, use:

cd -- "$(dirname -- "$BASH_SOURCE")"

In this invocation scenario, the following POSIX-compliant variation, which uses $0 in lieu of $BASH_SOURCE, would work too: cd -- "$(dirname -- "$0")"

Note:

  • Generally, if your script is invoked via a symlink and you want to change to the target's directory (the actual script file's directory as opposed to the directory in which the symlink is located), more work is needed - see this answer of mine.

  • When opening a script from Finder, however, this issue does not apply, because Finder itself resolves a symlink to its (ultimate) target and then invokes the target directly.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • i dont understand what u mean by invoked via symlink ? – Sech Jul 07 '17 at 13:56
  • @Sech: Re symlink: Let's say your script is `~/foo` and you create a symlink to it in `/usr/local/bin`: `ln -s ~/foo /usr/local/bin/foo`. When you then invoke `foo` from `/usr/local/bin` rather than from `~`, the above command will change to `/usr/local/bin`. – mklement0 Jul 07 '17 at 14:02
1

The problem with your script is that it runs with a different working directory than you tested it with. When you do ls something in a script, the script looks in the current working directory (where you cded last in case you're in a terminal), not in the directory the script is in. In general, when writing scripts like this you should use the full path of the file you're referring to or figure out the directory of the script and point to the file relative to that. One solution works in Bash, but it might not in the shell you're using.

l0b0
  • 55,365
  • 30
  • 138
  • 223