3

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 ???

1
  • 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. Commented Jul 7, 2017 at 16:37

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

i dont understand what u mean by invoked via symlink ?
@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.
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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.