running a script from another script - macos

I have a script located at /tmp/"My Batch Script Files"/Processing
How would I run this from the home directory /tmp/ in another script

If it is executable:
"/tmp/My Batch Script Files/Processing" arg1 arg2 ...
If it is not exectuable, either make it executable or:
bash "/tmp/My Batch Script Files/Processing" arg1 arg2 ...
You can place the double quotes around the whole path name as I did, or around the component containing the spaces, or almost any other location you choose in between. With just two double quotes, this as close together as you can place them:
/tmp/My" Batch Script "Files/Processing arg1 arg2 ...
or use backslashes if you prefer (I don't recommend them, though):
/tmp/My\ Batch\ Script\ Files/Processing arg1 arg2 ...
On the whole, though, I'd go with the first suggestion, or use:
proc_script="/tmp/My Batch Script Files/Processing"
"$proc_script" arg1 arg2 ...
This is particularly attractive if you generate the file name while the outer script is running.

Related

Bash script executing a binary

I have a bash script that I am modifying. The script now also executes a binary. Say something like this
mybin arg1 arg1 The binary takes about 5 minutes to execute and when I execute it from bash directly, it does show the intermediate outputs. When I add it to my script as
`mybin arg1 arg1`
I get the output in the end and bash thinks the output is a command and tries to execute it. So I want to solve 2 things
Show the intermediate output on the screen when I execute the binary from the bash script.
And the output must not be treated to be a command for processing, just regular output
Remove the backticks.
`prog` means "collect the output of prog and interpolate it into the current command", so if `prog` is the only thing on the command line, its output will be executed as another command. This is known as command substitution.
In other words, the two things you don't want to happen are exactly what ` ` is designed to do.

Create alias in shell script using a variable

I have a directory say "/dir". Inside this directory I have files with the name arg1_config.tcl, arg2_config.tcl, arg3_config.tcl. There might be more files going forward with the same extension. I am trying to dynamically generate aliases for arg1, arg2 and arg3 in this case and below is my code for the same.
foreach i (`ls <path>/dir/*.tcl`)
set app = `echo $i | sed -e 's/.*\///g' | sed 's/_config.tcl//g'`
echo "app is $app"
alias $app 'run -app $app' # run is an internal script that takes arg1/2/3 as a switch
echo "alias $app 'run -app $app'"
end
When I source this file it prints
app is arg1
alias arg1 'run -app arg1'
app is arg2
alias arg2 'run -app arg2'
app is arg3
alias arg3 'run -app arg3'
However when I run which arg3 it says aliased to run -app $app and app value somehow is always the last value after exiting the foreach loop i.e arg3 in this case. I am not able to create aliases like the print messages above, i.e:
alias arg1 'run -app arg1'
alias arg2 'run -app arg2'
alias arg3 'run -app arg3'
I know it's a bash faq, but the ParsingLs guidelines apply here too. Don't parse the output of ls. Just don't. You have globs in csh too.
foreach i (`ls <path>/dir/*.tcl`)
should simply be
foreach i ( <path>/dir/*.tcl )
That said, the problem you're asking about is as Glenn suggested in comments. Single and double quotes behave in csh much the same way as they do in sh/bash: single quotes block variable expansion. Your alias is not actually setting an alias, it's setting something which when run will try to expand the variable at the time you run it. Try using double quotes and see if that gets you the behaviour you expect.
As an alternate strategy to shell aliases, consider linking or symlinking the script to multiple names on your path, then switching on $0 instead. It'll require less hacking on shells, which will be especially noticeable when someone decides to try out a different shell and forgets that these "commands" are really just shell aliases. :)

How to call another shell script from a shell script in Unix

I am trying to call another shell script from inside a shell script in unix (bash)
1st Shell script(script_1.sh):
VARIABLE_1=<VALUE>
<unix_code>
<unix_code>
..
..
..
export VARIABLE_1
bash -x script_2.sh
bash -x script_3.sh
my requirement here is to pass the value of VARIABLE_1 to script_2.sh & script_3.sh. I was able to execute script_2.sh pass the argument to script_2.sh and it was working fine. Problem has started when i included script_3.sh. It gives me below error, when i execute the first shell script.
/usr/bin/sh: /usr/bin/sh: cannot execute binary file
Not sure why this happening. Also, Is this recommended way to pass arguments and call other shell scripts ? Please let me know
cannot execute binary file does not mean the file lacks execute permissions. In fact, running a script as "bash filename", does not need the executable permissions on the filename.
The error message is telling you that the script file is not an actual script file, but a binary file, probably an executable. If that is the case, do not do:
bash +x filename
just do:
filename
Additionally, to pass arguments to the script, you can do so like this:
scriptfile arg1 arg2 arg3
then refer inside your script as $1, $2, $3. Or $*to refer to all of them.
EDIT:
Also note that to execute a script you do not need to use bash scriptfile, you may just run scriptfile. In that case, scriptfile must have the executable permission (i.e., chmod +x scriptfile). Additionally, if the file is in the current directory, but the . is not part of the PATHvariable, the scriptfile will not be found. In that case you should execute your scriptfile as ./scriptfile
Your script would change to:
VARIABLE_1=<VALUE>
...
./script_2.sh "$VARIABLE_1"
./script_3.sh "$VARIABLE_1"
You no longer need to export the VARIABLE_1. The quotes are necessary to make sure the contents of VARIABLE_1 are passed as a single argument. script_2.sh and script_3.sh will see the value as $1. If the VARIABLE_1 has spaces in it, and you omit the quotes, each word will be pass as a separate value. That is, $1 will have the first word, $2the second, etc.
script_3.sh may not have permission to execute. Use chmod to provide appropriate permission and try again

How to pass arguments to a bash script running under MinGW on Windows

I have a bash script which takes two arguments .
On OS X I can invoke the script as follows:
./my-script arg1 arg2
and both arguments are passed to the script.
I have MinGW installed on Windows and when I invoke the script as follows:
my-script arg1 arg2
the arguments are not passed to the script.
However if I invoke it as follows:
bash my-script arg1 arg2
the arguments are passed to the script.
Is there is another way to pass the arguments without having to do this?
In OS X/Linux the terminal itself is bash and that can process shell script. But in the case of windows it does not use bash for terminal that is why you want install mingw to get bash itself. So if you want to execute scipt you want to execute bash and then input the script. So in command prompt you have to give bash my-script arg1 arg2. In windows explorer you can set *.sh extension to bash so by clicking on script it will execute bash. But you can't give arguments for scripts. In conclusion it is not possible to execute shell scripts without giving bash.
For windows my suggestion is to go with powershell scripts which is new or old batch scripts.

Can I pipe between commands, and run the programs from different directories?

I have a particular command, that reacts differently depending on the content of the current working directory.
I now wish to pipe this program back to itself, back have the call happen in different directories.
In "pseudo-bash", I want
command arg1 | cd /other dir | command arg2
I personally use bash, but if it helps to use a different shell, I'm open to suggestions. :)
I realize there is a very easy workaround with a temporary file or named pipe, but I want to know if there's a way to do this in one command.
command arg1 | ( cd /other_dir ; command arg2 )
(…) executes a command in a subshell. cd is a shell builtin command, not a 'real process'. ( cd X ; command ) will start a new sub-shell, cd into X, then run command. command is running as a process, but in a different directory.
Going forward it's better to have commands that can take a directory as an argument (and if not defined, default to the current working directory). Then you could have the simple solution of command arg1 | command --dir=/other_dir arg2
How about using a subshell, something like this:
command arg1 | (cd /other/dir; command arg2)
Pipes don't work that way. They are simply a way to pass data streams (not context) from one command to another. If you need a command in a pipeline to run in a different context from the others, you'll just have to change the directory in that subshell, as #JoachimPileborg pointed out.
The canonical way to solve this in *nix shells is to instead pass the relevant directory as a parameter to the script. Your command sequence would then be:
command arg1 .
command arg2 /other/dir

Resources