How to properly do Multiple Command Substitution in bash - bash

I am trying to have a variable execute 2 commands when typed in the terminal, namely change to a specific directory and run an executable. However when executed it returns
bash: cd: too many arguments
This is how I defined the variable in .bashrc
export FOO='cd "/path/to/directory" ; /path/to/executable'
When I input this line directly it works fine. So what is the proper way of defining such a variable?

After the suggestion by Barmer and Gordon and a quick search I managed to achieve the result I wanted using functions.

Related

Run simple programme using unix shell

I'm new to unix and its developing. In my new.sh script I wrote
$USERNAME=user
$PASSWORD=sekrit
echo $USERNAME
and ran new.sh using bash new.sh
But I get the following errors
new.sh: line 1: =user: command not found
new.sh: line 2: =sekrit: command not found
How do I run that command and print the username variable in terminal?
USERNAME is the name of the variable. $USERNAME is the replacement (aka contents, aka value). Since USERNAME is empty, you effectively try to run a command named =user, which is what the error message tells you.
Remove the $ from $USERNAME=... and it will work.
As Jens notes in his answer, the problem is that an assignment to a variable is not prefixed with a $, so:
USERNAME=user
PASSWORD=sekrit
is the way to write what you wanted. You got an error because USERNAME was not set, so after expansion, the shell looked at the command as:
=user
=sekrit
and it could not find such commands on the system (not very surprisingly). However, be aware that if you have previously written:
USERNAME=archipelago
PASSWORD=anchovy
then the lines:
$USERNAME=user
$PASSWORD=sekrit
would have been equivalent to writing:
archipelago=user
anchovy=sekrit
You could see that by running set with no arguments; it would show you the values of all the variables set in the shell. You could search for words such as USERNAME and archipelago to see what happened.
Now you've learned that, forget it. The number of times you'll need to use it is very limited (but it is handy on those rare — very rare — occasions when you need it).
For all practical purposes, don't write a $ on the left-hand side of a variable assignment in shell.

"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.

Using custom script inside .profile file in ksh

I am trying to use a script that takes in some parameters inside my .profile file. The script is basically to execute a particular operation(from a set) on a list of jobs. So I execute the script like this.
sh bulkCommandProcessor.sh commandName job1 job2 job3...
Since the number of commands that can go in as the first argument is only 7, I would like to have aliases for each of it in my .profile file. I tried the following.
alias bjr='sh /home/vijay/scripts/bulkCommandProcessor.sh jr'
However, this doesnt seem to work. The error handling part of my code gets displayed when I source the .profile file which says something like this.
usage: /home/vijay/scripts/bulkCommandProcessor.sh cmd Job_name1 Job_name2 Job_name3 ..
Is there a way to achieve what I intend? That is use a script that accepts variable length of arguments within the .profile file.
First I think you need to make sure that your script bulkCommandProcesor.sh has the right permissions, that it is in the right path and that your are correctly parsing arguments for your script. I think that the following template might work:
#!/usr/bin/ksh
# .profile example
alias bjr='sh /home/vijay/scripts/bulkCommandProcessor.sh jr'
#variable length arguments in jobs
#where you previously get job1,job2 for example
jobs="$job1 $job2"
#And finally calling your script
bjr $jobs

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

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!

Difference between launching a script with ./script.sh and . ./script.sh

Please tell me what is the difference in bash shell between launching a script with
./script.sh and . ./script.sh?
As klausbyskov says, the first form requries that the file have its executable permission bit set.
But more importantly, the first form executes the script in a separate process (distinct from, independent of, and unable to make changes in the shell that launched it). The second form causes the initial shell to directly run the commands from the file (as if you had typed them into the shell, or as if they were included in the script that does the ‘sourcing’).
A script that contains FOO=bar; export FOO will have not create an exported FOO environment variable in the shell that runs the first variant, but it will create such a variable in a shell that runs the second variant.
The second form (‘sourcing’) is a bit like a #include in C.
The first requires the file to have the +x flag set. The second uses the . command aka "source", described here.

Resources