Run next command in script after invoking singularity shell - bash

I have a shell script with multiple singularity commands in it
myscript.sh
#!/bin/sh/
singularity shell -B /home/user/Desktop/ /home/user/image/some_image.simg
/home/user/miniconda/activate my_env
cd /app/app_folder/scripts
ls -ash
when i run the script it get stuck after the shell is invoked.
singularity>
However I want the subsequent commands to run in the invoked shell. How do I go about this?

YOu are connecting to an interactive command shell inside a shell script, what you need is only execute the commands.
singularity exec ...
https://sylabs.io/guides/3.7/user-guide/cli/singularity_exec.html

So basically I had to replace shell with exec and save the subsequent commands in a different executable bash script newscript.sh which contains
#!/bin/sh
/home/user/miniconda/activate my_env
cd /app/app_folder/scripts
ls -ash
and then run myscript.sh
#!/bin/sh
singularity exec -B /home/user/Desktop/ /home/user/image/some_image.simg bash newscript.sh
This method will run newscript.sh in the singularity shell after the singularity shell is invoked in myscript.sh

Related

Source a tcsh script from bash

I'm trying to execute a tcsh script in a bash environment. My regular environment is tcsh so the following command works for me:
source /usr/scripts/my_setup -t abs
But I need to execute this command from some third party software which runs the commands on bash shell. This script should set an environment variable $TMP.
I already tried all the suggested solutions from the previous threads and they all do not work.
What I tried:
tcsh -c "source /usr/scripts/my_setup -t abs ; exec bash"
tcsh -c "source /usr/scripts/my_setup -t abs ; bash"
The following steps:
echo "tcsh -c 'source /usr/scripts/my_setup -t abs'" > setup
chmod a+x setup
source setup
They all fail. And I understand why (everytime I use tcsh it opens a new shell). But I can't seem to understand how to source a tcsh script from bash.

Proper syntax for bash exec

I am trying to do the following:
if ps aux | grep "[t]ransporter_pulldown.py" > /dev/null
then
echo "Script is already running. Skipping"
else
exec "sudo STAGE=production $DIR/transporter_pulldown.py" # this line errors
fi
$ sudo STAGE=production $DIR/transporter_pulldown.py works on the command line, but in a bash script it gives me:
./transporter_pulldown.sh: line 9:
exec: /Users/david/Desktop/Avails/scripts/STAGE=production
/Users/david/Desktop/Avails/scripts/transporter_pulldown.py:
cannot execute: No such file or directory
What would be the correct syntax here?
sudo isn't a command interpreter thus its trying to execute the first argument as a command.
Instead try this:
exec sudo bash -c "STAGE=production $DIR/transporter_pulldown.py"
This creates uses a new bash processes to interpret the variables and execute your python script. Also note that $DIR will be interpreted by the shell you're typing in rather than the shell that is being executed. To force it to be interpreted in the new bash process use single quotes.

Difference between "./" and "sh" in UNIX

Sometimes i see that few scripts are executed through "sh" command and sometimes through "./" command.I am not able to understand the exact difference between them.Please help me out .
sh file executes a shell-script file in a new shell process.
. file executes a shell-script file in the current shell process.
./file will execute the file in the current directory. The file can be a binary executable, or it can start with a hashbang line (the first line of the file in form of #!...., for example #!/usr/bin/ruby in a file would signify the script needs to be executed as a Ruby file). The file needs to have the executable flag set.
For example, if you have the script test.sh:
#!/bin/sh
TEST=present
and you execute it with sh test.sh, you'd launch a new sh (or rather bash, most likely, as one is softlinked to the other in modern systems), then define a new variable inside it, then exit. A subsequent echo $TEST prints an empty line - the variable is not set in the outer shell.
If you launch it using . test.sh, you'd execute the script using the current shell. The result of echo $TEST would print present.
If you launch it using ./test.sh, the first line #!/bin/sh would be detected, then it would be exactly as if you wrote /bin/sh ./test.sh, which in this case boils down to the first scenario. But if the hashbang line was, for example, #!/usr/bin/perl -w, the file would have been executed with /usr/bin/perl -w ./test.sh.
In simple words, sh file1 executing sh command/executable with file1 as a parameter. In this case file1 doesn't require execute privilege as sh executable read and intercept the commands in the file.
./file1 its nothing but running/executing an executable file file1, hence it requires executable privileges. In this case it executes on the shell mentioned in the shebang #!/bin/sh if its not mentioned then its on the current shell.
Hoping the above statements are not chaos :)
With sh , we can run a script that doesn’t have execute permission set on it, we run it as argument for sh, but ./ needs the permission as it is supposed to be an executable.
In both cases, new shell will be created to run the script. See the below example:
root#ub18:~/shell# vi test1.sh
#!/bin/bash
my_var=hello
echo $my_var
#Shows the current shell processid
echo $$
root#ub18:~/shell# echo $$
1896
root#ub18:~/shell# sh test1.sh
hello
2093
root#ub18:~/shell# ./test1.sh
-su: ./test1.sh: Permission denied
root#ub18:~/shell# chmod +x ./test1.sh
root#ub18:~/shell# ./test1.sh
hello
2102
root#ub18:~/shell# ./test1.sh
hello
2103
root#ub18:~/shell# ./test1.sh
hello
2104
root#ub18:~/shell# sh test1.sh
hello
2106
when your file is not executable you can't run using ./file_name.sh normally you can run by sh file_name.sh if you change your file to executable chmod a+x file_name.sh you can run your file by ./file_name.sh

Output of a shell script is another shell script

I have a shell script which will print another shell script to stdout. I need to execute both the scripts (initial script and output script) with a single line bash command. Is it possible?
Maybe something like that:
sh ./test.sh | sh
Try doing this :
bash test.bash | bash -s

How to specify zeroeth argument

I'm writing a bash script that starts the tcsh interpreter as a login shell and has it execute my_command. The tcsh man page says that there are two ways to start a login shell. The first is to use /bin/tcsh -l with no other arguments. Not an option, because I need the shell to execute my_command. The second is to specify a dash (-) as the zeroeth argument.
Now the bash exec command with the -l option does exactly this, and in fact the following works perfectly:
#!/bin/bash
exec -l /bin/tcsh -c my_command
Except... I can't use exec because I need the script to come back and do some other things afterwards! So how can I specify - as the zeroeth argument to /bin/tcsh without using exec?
You can enclose the exec command into a sub-shell of your script.
#!/bin/bash
(exec -l /bin/tcsh -c my_command)
# ... whatever else you need to do after the command is done
You can write a wrapper (w.sh) script that contains:
#!/bin/bash
exec -l /bin/tcsh -c my_command
and execute w.sh in your main script.

Resources