I'd like to use Nashorn for shell scripting, however I can't find the analog of the Bash variable $0 which tells me the path of the running script so that I could launch other scripts that are in the same folder (this is different from the working directory).
The __DIR__ and __FILE__ values available in Nashorn JavaScript will help you implementing a substitute for $0. The former gives you the current file's directory; the latter, the file name.
Related
I am used to running shell scripts with for example
source script.sh
I was surprised to learn recently that this also works
. script.sh
The single dot of course normally indicates the current directory so I am now confused. Can anyone explain this use of .?
Taken from IBM docs: ".(dot) runs a shell script in the current environment and then returns. Normally, the shell runs a command file in a child shell so that changes to the environment by such commands as cd, set, and trap are local to the command file. The . (dot) command circumvents this feature.
If there are slashes in the file name, . (dot) looks for the named file. If there are no slashes . (dot) searches for file in the directories specified in the PATH variable. This may surprise some people when they use dot to run a file in the working directory, but their search rules are not set up to look at the working directory. As a result, the shell does not find the shell file."
. (dot) and source mean the same thing in the bash language.
In fact the (dot) form is the standard form according to the POSIX Shell Specification. The source form is a bash extension, but not a bash invention. (The venerable Berkley C-shell (csh) used to use source rather than ..)
According to the POSIX Shell specification, source is a command name whose meaning is unspecified; see https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
I would like to write a script that has several commands of the kind
> export PATH=$PREFIX/bin
Where
> $PREFIX = /home/usr
or something else. Instead of typing it into the the Shell (/bin/bash) I would run the script to execute the commands.
Tried it with sh and then with a .py script having the line,
> commands.getstatusoutput('export PATH=$PREFIX/bin')
but these result into the error "bad variable name".
Would be thankful for some ideas!
If you need to adjust PATH (or any other environment variable) via a script after your .profile and equivalents have been run, you need to 'dot' or 'source' the file containing the script:
. file_setting_path
source file_setting_path
The . notation applies to all Bourne shell derivatives, and is standardized by POSIX. The source notation is used in C shell and has infected Bash completely unnecessarily.
Note that the file (file_setting_path) can be specified as a pathname, or if it lives in a directory listed on $PATH, it will be found. It only needs to be readable; it does not have to be executable.
The way the dot command works is that it reads the named file as part of the current shell environment, rather than executing it in a sub-shell like a normal script would be executed. Normally, the sub-shell sets its environment happily, but that doesn't affect the calling script.
The bad variable name is probably just a complaint that $PREFIX is undefined.
Usually a setting of PATH would look something like
export PATH=$PATH:/new/path/to/programs
so that you retain the old PATH but add something onto the end.
You are best off putting such things in your .bashrc so that they get run every time you log in.
I have a shell script on a mac (OSX 10.9) named msii810161816_TMP_CMD with the following content.
matlab
When I execute it, I get
./msii810161816_TMP_CMD: line 1: matlab: command not found
However, when I type matlab into the shell directly it starts as normal. How can it be that the same command works inside the shell but not inside a shell script? I copy-pasted the command directly from the script into the shell and it worked ...
PS: When I replace the content of the script with
echo matlab
I get the desired result, so I can definitely execute the shell script (I use ./msii810161816_TMP_CMD)
Thanks guys!
By default, aliases are not expanded in non-interactive shells, which is what shell scripts are. Aliases are intended to be used by a person at the keyboard as a typing aid.
If your goal is to not have to type the full path to matlab, instead of creating an alias you should modify your $PATH. Add /Applications/MATLAB_R2014a.app/bin to your $PATH environment variable and then both you and your shell scripts will be able to simply say
matlab
This is because, as commenters have stated, the PATH variable inside of the shell executing the script does not include the directory containing the matlab executable.
When a command name is used, like "matlab", your shell looks at every directory in the PATH in order, searching for one containing an executable file with the name "matlab".
Without going into too much detail, the PATH is determined by the shell being invoked.
When you execute bash, it combines a global setting for basic directories that must be in the PATH with any settings in your ~/.bashrc which alter the PATH.
Most likely, you are not running your script in a shell where the PATH includes matlab's directory.
To verify this, you can take the following steps:
Run which matlab. This will show you the path to the matlab executable.
Run echo "$PATH". This will show you your current PATH settings. Note that the directory from which matlab is included in the colon-separated list.
Add a line to the beginning of your script that does echo "$PATH". Note that the directory from which matlab is not included.
To resolve this, ensure that your script is executed in a shell that has the needed directory in the PATH.
You can do this a few ways, but the two most highly recommended ones would be
Add a shebang line to the start of your script. Assuming that you want to run it with bash, do #!/bin/bash or whatever the path to your bash interpreter is.
The shebang line is not actually fully standardized by POSIX, so BSD-derived systems like OSX will happily handle multiple arguments to the shebanged executable, while Linux systems pass at most one argument.
In spite of this, the shebang is an easy and simple way to document what should be used to execute the script, so it's a good solution.
Explicitly invoke your script with a shell as its interpreter, as in bash myscript.sh or tcsh myscript.sh or even sh myscript.sh
This is not incompatible with using a shebang line, and using both is a common practice.
I believe that the default shell on OSX is always bash, so you should start by trying with that.
If these instructions don't help, then you'll have to dig deeper to find out why or how the PATH is being altered between the calling context and the script's internal context.
Ultimately, this is almost certainly the source of your issue.
My ruby shell scripts specify the ruby interpreter in the first line of the script as:
#!/Users/me/.rvm/rubies/ruby-1.9.3-p194/bin/ruby
The problem is that when I upgrade to a new ruby version, I have to edit all the script files to update the interpreter. There is an environment variable available, $MY_RUBY_HOME, that expands to the current path (minus the /bin/ruby part). However, all my attempts to use:
#!{$MY_RUBY_HOME}/bin/ruby
#!${MY_RUBY_HOME}/bin/ruby
etc
fail ("bad interpreter: No such file or directory"). I suspect environment expansion isn't done on the first line, so I may just be out of luck. I would be interested if anybody has been able to use environment variable expansion on the program definition line in a shell script.
Put ${MY_RUBY_HOME}/bin in your $PATH and use #!/usr/bin/env ruby. See here.
I tried the following two ways to source the property file
#!/bin/sh
. import.properties
echo $USER_ID
echo $INPUT_FILE
It says :
./test.sh[3]: import.properties: not found
when tried using source import.properties it gave the message as:
./test.sh[3]: source: not found.
I am very new to the scripting and env. Please let me know what I am missing here?
To be found by the dot . command, the file must be readable (not necessarily executable) and on your PATH (and to be safely usable, it must contain shell script).
If the file is in your current directory and . (the directory, not the command) is not on your PATH, you can use:
. ./import.properties
Otherwise, you need to specify the absolute name of the file, or relative name of the file, or move the file to a convenient directory on your PATH.
The alternative notation, source import.properties fails because you are not in the C Shell, and because you are not using Bash. The source command in the C Shell is the analogue of the dot command in the Bourne shell. Bash allows it as a synonym for the dot command (or the dot command as a synonym for source). Since source was not found, we can safely assume your shell does not support it as a built-in.