nohup VERBOSE=1 perl script.pl - shell

I have a perl script for which ENV variables can be set to direct specific outputs
e.g. $debug, $verbose, $develop etc
Usually I run these from the command line
$ VERBOSE=1 perl myperlscript.pl params
I now want to run them using nohup. Using the command line
$ nohup VERBOSE=1 perl myperlscript.pl params
is clearly not right, as the attempt to set ENV{VERBOSE} is interpreted as a param to nohup & I get the msg
nohup: failed to run command `VERBOSE=1': No such file or directory
What IS the correct syntax here? I'm trying to run this on a linux box.

Set the environment variable before calling nohup, and it will be preserved when nohup exec()s (replaces itself with) perl.
$ VERBOSE=1 nohup perl myscript.pl params ...

This is exactly what the env command is for:
$ env VAR1=VAL1 VAR2=VAL2 nohup perl myperlscript.pl params &

Try to combine all commands into shell script and run it like that:
nohup /path/to/script.sh
Or you could use export:
export VERBOSE=1
And then:
nohup perl myperlscript.pl params

Related

How do I translate this bash function to fish shell?

function run () {
nohup python $1 > nohup.out &
}
On the command line I call this as "run scriptname.py" and bash executes the following command:
python scriptname.py > nohup.out &
Can you help me translate this to fish.
I have this so far..
function run
bash -c "nohup python $1 > nohup.out &"
end
When I call source on ~/.config/fish/config.fish
This exists simply saying
Error when reading file: ~/.config/fish/config.fish
without providing any helpful hints as to what the error is.
There's really no need to execute bash here, fish can also execute nohup, the redirections also work and such.
There's a minor difference in that, instead of $1 and $2 and so on, arguments to fish functions are stored in the $argv array.
function run
nohup python $argv > nohup.out &
end
This will expand $argv to all elements of that as one element each, so run script.py banana would run nohup python script.py banana > nohup.out &. If you truly want just one argument to be passed, you'd need $argv[1].
I actually have no idea why your definition should cause an error when sourcing config.fish - which fish version are you using?
This is a perfectly valid (and more correct) replacement for your function in fish:
function run
bash -c 'nohup python "$#" > nohup.out &' _ $argv
end
This is an equivalent to the native-bash function:
run() {
nohup python "$#" </dev/null >nohup.out 2>&1 &
}
...which, personally, I would suggest rewriting to use disown rather than nohup.
With respect to the error seen from fish, I'd suggest paying attention to any other (not syntax-related) which may have impacted whether your file could be read -- permissions, etc.

perl how to finish the script by 'cd $newdir'

I have a perl script that creates a directory $newdir based on some input passed as a parameter, and I would like the script to finish it's execution by doing:
cd $newdir
So that the next command in bash Linux 64bit (here program2) is executed from the $newdir working directory.
E.g.:
perl $HOME/import_script.pl -i someparameter && $HOME/program2 .
You can't.
Any cd (or similar) you run in the perl script will affect only the perl script (or a sub-shell spawned from the perl script).
It can't affect the parent shell directly.
The only thing you could do would be to output the directory and then cd to that or similar. (e.g. cd "$(perl "$HOME"/import_script.pl -i someparameter)" && "$HOME/program2" . but realize that this means you can't output anything else to standard output from the perl script or it will confuse cd.)
Or have perl run the second command also, etc.
Just adding another potential solution here; you can have your perl script output the bash you want to run, and run it with bash eval. For example;
File: do.pl:
#!/usr/bin/env perl
use strict;
use warnings;
use File::Temp qw(tempdir);
my $dir = tempdir();
print "echo Whatever I print out will be evaluated in my shell;";
print "cd $dir"; # Separate multiple commands with ';', see ^
From Bash
[~] > eval `./do.pl`
[~] > Whatever I print out will be evaluated in my shell
[/tmp/BcZI6ZaRB] > _
You can make things even easier by adding an alias, or bash function to your shell.
Add to File: ~/.bashrc
doit() {
eval $(./do.pl)
}
From Bash
[~] > doit
[~] > Whatever I print out will be evaluated in my shell
[/tmp/ejzVGauPXx] > _

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.

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.

Bash: Syntax error: redirection unexpected

I do this in a script:
read direc <<< $(basename `pwd`)
and I get:
Syntax error: redirection unexpected
in an ubuntu machine
/bin/bash --version
GNU bash, version 4.0.33(1)-release (x86_64-pc-linux-gnu)
while I do not get this error in another suse machine:
/bin/bash --version
GNU bash, version 3.2.39(1)-release (x86_64-suse-linux-gnu)
Copyright (C) 2007 Free Software Foundation, Inc.
Why the error?
Does your script reference /bin/bash or /bin/sh in its hash bang line? The default system shell in Ubuntu is dash, not bash, so if you have #!/bin/sh then your script will be using a different shell than you expect. Dash does not have the <<< redirection operator.
Make sure the shebang line is:
#!/bin/bash
or
#!/usr/bin/env bash
And run the script with:
$ ./script.sh
Do not run it with an explicit sh as that will ignore the shebang:
$ sh ./script.sh # Don't do this!
If you're using the following to run your script:
sudo sh ./script.sh
Then you'll want to use the following instead:
sudo bash ./script.sh
The reason for this is that Bash is not the default shell for Ubuntu. So, if you use "sh" then it will just use the default shell; which is actually Dash. This will happen regardless if you have #!/bin/bash at the top of your script. As a result, you will need to explicitly specify to use bash as shown above, and your script should run at expected.
Dash doesn't support redirects the same as Bash.
Docker:
I was getting this problem from my Dockerfile as I had:
RUN bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)
However, according to this issue, it was solved:
The exec form makes it possible to avoid shell string munging, and
to RUN commands using a base image that does not contain /bin/sh.
Note
To use a different shell, other than /bin/sh, use the exec form
passing in the desired shell. For example,
RUN ["/bin/bash", "-c", "echo hello"]
Solution:
RUN ["/bin/bash", "-c", "bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)"]
Notice the quotes around each parameter.
You can get the output of that command and put it in a variable. then use heredoc. for example:
nc -l -p 80 <<< "tested like a charm";
can be written like:
nc -l -p 80 <<EOF
tested like a charm
EOF
and like this (this is what you want):
text="tested like a charm"
nc -l -p 80 <<EOF
$text
EOF
Practical example in busybox under docker container:
kasra#ubuntu:~$ docker run --rm -it busybox
/ # nc -l -p 80 <<< "tested like a charm";
sh: syntax error: unexpected redirection
/ # nc -l -p 80 <<EOL
> tested like a charm
> EOL
^Cpunt! => socket listening, no errors. ^Cpunt! is result of CTRL+C signal.
/ # text="tested like a charm"
/ # nc -l -p 80 <<EOF
> $text
> EOF
^Cpunt!
do it the simpler way,
direc=$(basename `pwd`)
Or use the shell
$ direc=${PWD##*/}
Another reason to the error may be if you are running a cron job that updates a subversion working copy and then has attempted to run a versioned script that was in a conflicted state after the update...
On my machine, if I run a script directly, the default is bash.
If I run it with sudo, the default is sh.
That’s why I was hitting this problem when I used sudo.
In my case error is because i have put ">>" twice
mongodump --db=$DB_NAME --collection=$col --out=$BACKUP_LOCATION/$DB_NAME-$BACKUP_DATE >> >> $LOG_PATH
i just correct it as
mongodump --db=$DB_NAME --collection=$col --out=$BACKUP_LOCATION/$DB_NAME-$BACKUP_DATE >> $LOG_PATH
Before running the script, you should check first line of the shell script for the interpreter.
Eg:
if scripts starts with /bin/bash , run the script using the below command
"bash script_name.sh"
if script starts with /bin/sh, run the script using the below command
"sh script_name.sh"
./sample.sh - This will detect the interpreter from the first line of the script and run.
Different Linux distributions having different shells as default.

Resources