Unexpected nohup behaviour - unix

I have an executable file test, it contains
a="$RANDOM"
echo "$a">>out
Now, if I simply ./test then out contains a random number. But if I nohup ./test & then out is empty. Why?

Transferring comment into an answer
Are you on Ubuntu (or another Linux distro)? Is /bin/sh a link to /bin/dash rather than /bin/bash? If so, when you run it with bash as your shell, then $RANDOM works, but when nohup runs it with /bin/sh (aka dash), you get nothing.
You might be able to fix it by using #!/bin/bash as the shebang line.
Actually I'm on Debian. But anyway I forgot the shebang indeed; now it works perfectly.
Great!
Incidentally, however tempting it is, it's generally a bad idea to call programs test because there is a shell built-in called test (also known as [) that can readily cause confusion if it is run instead of your test program.

Related

WSL PATH environment variable is incorrect / zsh config not loaded [duplicate]

I am using Ubuntu via WSL 2.0 on Windows 10 and would like to run Texlive from the Windows command line. To do so I prepended the Texlive folder to the path in /etc/environment (I also tried a number of other locations eg. $HOME/.bashrc):
C:\Users\scott\Documents>wsl echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/mnt/c/Windows/system32:...
C:\Users\scott\Documents>wsl
scott#SCOTT-PC:/mnt/c/Users/scott/Documents$ echo $PATH
/usr/local/texlive/2020/bin/x86_64-linux:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/mnt/c/Windows/system32:...
Why is there a difference between these two paths? Is it possible to change the first PATH variable?
To be honest, when I first looked at this question, I thought it would be an easy answer. Oh how wrong I was. There are a lot of nuances to how this works.
Let's start with the fairly "easy" part, though. The main difference between the first method and the second:
wsl by itself launches into a login (and interactive) shell
the shell launched with wsl echo $PATH is neither a login shell nor an interactive shell
So the first will source both login scripts (e.g. ~/.profile) and interactive startup scripts (e.g. ~/.bashrc). The second form does not get to source either of these.
You can see this a different way (and get to the solution) with the following commands:
wsl -e bash -c 'echo $PATH'
wsl -e bash -li -c 'echo $PATH'
The -li forces bash to run as a login and interactive shell, thus sourcing all of the applicable startup scripts. And, as #bovquier points out in the comments, a single quote is needed here to prevent PowerShell from interpolating the $ before it gets to Bash. That, or escape it.
You should be able to run TeX Live the same way, just replacing the "echo $PATH" with the startup command you need for TeX Live.
A second option would be to create a script that both adds the path and runs the command, and just launch that script through wsl /path/to/script.sh
That said, I honestly don't think that your current login/interactive PATH is coming from /etc/environment. In my testing, at least, /etc/environment has no use in WSL, and that's to be expected. /etc/environment is only sourced by PAM modules, and with no login check performed by WSL, there's no reason to invoke PAM in either the wsl nor the wsl echo $PATH commands.
I'd expect that you still have the PATH setting in ~/.bashrc or somewhere similar), and that's where the shell is picking it up from at the moment.
While this isn't necessarily critical to understanding the answer, you might also wonder, if /etc/environment isn't used for setting the default (non-login, non-interactive) path in WSL, what is? The answer seems to be that it is hard-coded into the init that starts up WSL. That init is also what appends the Windows path (assuming you don't have that feature disabled in /etc/wsl.conf).

R system() doesn't behave like cmd itself

I'm doing some bioinformatics analysis in Rstudio, but something strange happens when using system(). I'm also using Windows Subsystem for Linux, so I can run a UNIX executable in my Windows cmd like so:
bash -c "./parasail-master/build/parasail_aligner -a sw_trace_striped_sat -f SSWtemplate.fa -q SSWtest.fa -O EMBOSS -d >OUT.txt"
Don't worry about the specifics: what's important is that I use bash -c to indicate I want to use the UNIX bash, and I'm running the executable parasail_aligner. It all works out, and I get the nice output file "OUT.txt".
Now, since I'm doing my analysis in Rstudio, I want to execute this directly from an R script, like so:
system('bash -c "./parasail-master/build/parasail_aligner -a sw_trace_striped_sat -f SSWtemplate.fa -q SSWtest.fa -O EMBOSS -d >OUTER.txt"')
So: just give it as an argument to system()? But this gives the following error:
input file, query file, and stdin detected; max inputs is 2
This is obviously an error specifically generated by parasail_aligner. The funny thing is: I don't get this error at all from cmd directly, but I do get it when running the command in R using system(). Does anyone have any idea why something like this can happen at all? I would expect system() to just give its argument to cmd, but clearly it doesn't do this... Running the command in a command terminal opened in Rstudio also works fine, it is specifically system() that seems to mess up.
I'm terribly sorry if this question is vague, but I can't give you a simple example which you could use to replicate the error. I've been using system() for a while now and I've never had this kind of problem. I am on Windows and I've found some people online that say you should use shell() instead of system(), but doing so just gives me the same error.
Maybe it has something to do with this "stdin" thing the error mentions and how R/RStudio handles this, I don't know. But parasail seems to think I give it an extra input "stdin": it is true I give an Input File and a Query File (see error message), but I don't know what this "stdin" is.
If anyone has any ideas about what could be behind this strange behaviour of system(), I'm all ears. I understand that helping me is difficult since I can't give a simple example in which the problem occurs, but I hope someone might know what could be the problem anyway
UPDATE (answer?): so, I managed to resolve the issue, like so:
system('bash -c "./parasail-master/build/parasail_aligner -a sw_trace_striped_sat < SSWtemplate.fa -f SSWtest.fa -O EMBOSS -d >OUTER.txt"')
I did some searching about stdin, and (forgive me if what I say sounds amateur, I'm not really familiar with UNIX or command line) found out its "symbol" is <. So you can see in the code above, I changed the way I give in my inputs "SSWtemplate" and "SSWtest", giving one of them using "<", and this solves the problem.
I have no idea why this happens. Especially since it only happens when calling the command from inside RStudio, and not when doing so from cmd. If anyone can clarify this further (i.e. why and how functions like system() and shell() seem to mess with stdin), it would be a big help. Otherwise, I'll just answer this to my own question and leave it at that.

Weird behaviour with zsh PATH

I just encourage a weird problem with zsh today.
My environment is Mac OS X Yosemite, zsh 5.0.5 (x86_64-apple-darwin14.0)
In .zshrc, I have manually set the PATH variable to something like
export PATH="$PATH:~/.composer/vendor/bin"
Try echo $PATH in terminal, the result is as expected (contained ~/.composer/vendor/bin). Then try executing a binary from ~/.composer/vendor/bin, It'll always return me "zsh: command not found" error.
Try switching to bash, echo $PATH is also as expected, have the same result as zsh shell.
Try executing a binary from ~/.composer/vendor/bin, no problem found. Seem the PATH var is acting well on the bash shell.
What's wrong with my zsh shell?
Thanks
Try using $HOME instead of ~. In many situations, shells do not expand ~ when you expect them to and it is usually better to use $HOME. ~ is really only intended to be a short cut for interactive use. (The only case I can recall where ~ was preferred was in a .gitalias, where ~ was expanded and variables were not.)
Type rehash to pick-up $PATH changes.
From the zsh user guide:
The way commands are stored has other consequences. In particular, zsh
won't look for a new command if it already knows where to find one. If
I put a new ls command in /usr/local/bin in the above example, zsh
would continue to use /bin/ls (assuming it had already been found). To
fix this, there is the command rehash, which actually empties the
command hash table, so that finding commands starts again from
scratch. Users of csh may remember having to type rehash quite a lot
with new commands: it's not so bad in zsh, because if no command was
already hashed, or the existing one disappeared, zsh will
automatically scan the path again; furthermore, zsh performs a rehash
of its own accord if $path is altered. So adding a new duplicate
command somewhere towards the head of $path is the main reason for
needing rehash.
EDIT However #WilliamPursell could be onto something with his comment:
note that "composer" != ".composer"

Command line app: Unix cd command

My Mac OS command line application is making Unix calls such as:
system("rm -rf /Users/stu/Developer/file);
perfectly successfully.
So why is the following not changing the current directory?
system("cd /Users/me/whatever");
system("pwd"); //cd has not changed
Because
system() executes a command specified in command by calling /bin/sh -c command, and returns after the command has been completed.
So each command is executed independently, each in a new instance of the shell.
So your first call spawns a new sh (with your current working directory), changes directories, and then exits. Then the second call spawns a new sh (again in your CWD).
See the man page for system().
The better solution is to not use system. It has some inherent flaws that can leave you open to security vulnerabilities. Instead of executing system() commands, you should use the equivalent POSIX C functions. Everything that you can do from the command-line, you can do with C functions (how do you think those utilities work?)
Instead of system("rm -rf ...") use this.
Instead of system("cd ...") use chdir().
Instead of system("pwd ...") use getcwd().
There are some differences, of course, but these are the fundamental equivalents of what you're trying to do.

Ksh Script automatically calling another script in /usr/bin

I am executing a ksh script named abs.ksh located at /app/fao.... which connects to a server,
But the server is receiving a script named "ksh" which is present in /usr/bin...
I am not calling any script called ksh in abs.ksh(sorry cannot paste the code).
Also this happens only when the script is run in debug mode.
In non debug mode it works fine.
Can anyone give me a hint of what might be happening here.
In a standard "classic" Unix environment there may be multiple shells. E.g. 'sh' the original Bourne shell, 'ksh' - the Korn shell, csh - the C shell, bash, tcsh etc. etc.. A user login will have the default shell set per login.
The #! at the start of an executable script is an instruction to interpret & run the subsequent text with the name of the program following the '#!'.
E.g. run this with perl
#!/bin/perl
<.. perl stuff ..>
So yes #!/usr/bin/ksh - will run the script with the command interpreter (shell) at that location.
Need more info. wrt how you run in debug mode. I.e. are you typing 'ksh -x ...' or 'sh -x' - if so where is that on your search path. E.g. 'whence ksh' - maybe you're running with a different shell in debug mode.
Also which os is this ?

Resources