Adding a shell script to be executed with the 'mrt/meteor create' command in terminal - shell

How can I run a shell script that is executed when I enter the 'mrt create' command in the terminal?

Great question Johann!
Alright, so to turn a shell script into something as convenient as a terminal command, all you need to do is create an alias for that script in your terminal's rc file. Further instructions as to how you can do that can be found here.
So all you need to do is list out the commands you want automated in the shell script, including the meteor/mrt commands, and pass the directory/project name with the special variable "$1" passes the first argument after your command into your script.
Here's the script I am currently using, which implements the folder structure from Discover Meteor and adds coffeescript and stylus-mixins There are probably some redundancies in commands. Let me know if you see anything that can be cleaned!

Related

AppleScript do shell script returns error for "which" command

I'm writing an AppleScript that will ask a user which remote cloud service and then which bucket they would like to mount in Mac OS using rclone. But in order to run the rclone command in an AppleScript, you need to include the entire path to the app. For me that is: /usr/local/bin/rclone
I want to include, as a variable, the location of rclone using the which command in a shell script like this:
set rcloneLOC to paragraphs of (do shell script "which rclone")
But I get a script error stating "The command exited with a non-zero status." This happens even if I just try to run do shell script "which rclone" by itself. If I type which rclone into terminal, I get the result I expect.
How do I get this to work?
As #GordonDavisson suggests, you can view your path using echo $PATH.
To change your applescript's path (and view the change) try this:
do shell script "export PATH=/usr/local/bin:$PATH ; echo $PATH"
The first part of the shell command (up to the semi-colon) will prepend /usr/local/bin to your default path. The second part will return your updated path. The semi-colon has the second part run after the first part is finished.
It's important to note that this change is temporary and only in effect for this shell script and only while it is operating. This is why you need the combined commands in order to see the effect.
I'll use 'rsync' as an example since I don't have rclone; substitute 'rclone' to get its path. To get its path, you combine the export command with which, like so:
do shell script "export PATH=/usr/local/bin:$PATH ; which rsync"
The result is /usr/local/bin/rsync.
To clarify a couple of things… the environment is a set of conditions that apply for each user. You can get a basic rundown of it by running man 7 environ in Terminal. There is an env command which lists your settings and allows you to edit them; man env will provide info on it. At the bottom of these man pages, you should see references to related commands which you can also look up. Meanwhile, from within Script Editor, you could run a 1-line script with do shell script "env" and see the corresponding environment for applescript's shell.
Based on Apple's documentation (or my interpretation of it), they chose this setup because it is relatively secure and portable. You know what you get every time you run a shell script. You don't need to use a more modern shell to run the which command. You can modify the environment as needed, the same way you would while using the terminal.
Finally, Apple has provided Technical Note 2065 which provides info on using shell scripts with applescript. Also, you can likely get more info here or on the unix stack exchange.
NB All of the above is just my understanding, which is limited.

"Command not found" inside shell script

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.

Bash interactive and non-interactive shell behaviour

I have a hard time with interactive and non-interactive shells. I don't understand which is which.
For example, I have read that non interactive shells usually check for the BASH_ENV variable on their startup and execute whatever it points to.
So, what I did is I set the BASH_ENV to point to some script which only echoes OK. Then I typed in bash in terminal and this script echoed OK. But why? Didn't I call yet another INTERACTIVE shell by typing bash in terminal, and not the other way around? Why did it execute the bash_env? I'm on linux mint maya.
The only thing you can be certain of is what's shown in the manpage for bash (see INVOCATION) - that lists in details what startup files are run in each instance.
However, there's nothing stopping (for example) one of those startup files running other files which would normally not be run.
By way of example, if .bash_profile had the following line:
. ~/.profile
it would also run the .profile script.
In fact the manpage states:
When bash is started non-interactively, to run a shell script, for example, it looks for the variable BASH_ENV in the environment, expands its value if it appears there, and uses the expanded value as the name of a file to read and execute. Bash behaves as if the following command were executed:
if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi
So, if you put that exact line in your startup scripts for an interactive shell like ~/.bash_profile, you'll also source the file pointed to by BASH_ENV.
Your best bet is to examine the INVOCATION section to find out which of the files will run, and then track through them (with something like set -x at the top of the script) to see what's getting called from where.
If memory serves, Bash is only interactive if you tell it, example
bash -i
So, by you calling just bash you invoked a non-interactive Bash.
More info
-i
If the -i option is present, the shell is interactive.

new to bash scripting; trying to figure out why SOURCE command doesn't execute

I have made a really sincere effort to figure this out, and I just can't. This is my very simple bash script. The lines that begin "export" and "echo" seem to work, so I know my script is executing. If I enter the line that begins "source" at the prompt in the terminal I get a lot of printed output that indicates that the command is running, but if I execute my script, nothing happens (and in fact subsequent efforts to use Freesurfer indicate that it hasn't worked). I have a feeling there may be something very basic I don't get about bash scripting, but I can't figure out what that thing is from looking at tutorials.
#!/bin/bash
export FREESURFER_HOME=/foo/freesurfer
echo "starting freesurfer"
echo $FREESURFER_HOME
source $FREESURFER_HOME/SetUpFreeSurfer.sh
export SUBJECTS_DIR=/bar/my_dir
If you run your script using ./scriptname.sh it is exexuted in a subshell. Every variable that is set there etc cannot change the environment of the parent shell. In order to do so you need to source the script.
See eg. this question on superuser

How do I set bash environment variables from a script?

I have some proxy settings that I only occasionally want to turn on, so I don't want to put them in my ~/.bash_profile. I tried putting them directly in ~/bin/set_proxy_env.sh, adding ~/bin to my PATH, and chmod +xing the script but though the script runs, the variables don't stick in my shell. Does anyone know how to get them to stick around for the rest of the shell session?
Use one of:
source <file>
. <file>
In the script use
export varname=value
and also execute the script with:
source set_proxy_env.sh.
The export keyword ensures the variable is marked for automatic inclusion in the environment of subsequently executed commands. Using source to execute a script starts it with the present shell instead of launching a temporary one for the script.
Did you try this:
. ~/bin/set_proxy_env.sh
Running it by itself opens a separate subshell (I think) and sets the variable there. But then the binding is lost after exiting back into your shell. The dot at the front tells it to run it within the same shell.
Also, don't forget to export the variables you need like so: export MYVAR=value

Resources