Can't start script via screen command - bash

I have a script, and I want to make it work in background after boot. Therefore, I added the command below into rc.local. However, it doesn't work.
sudo -iu executerroot screen -dmS test bash -c "bash /home/pi/FileServer/Run; exec bash"
Also I've tried commands in https://askubuntu.com/questions/261899/run-a-screen-session-on-boot-from-rc-local site but no one worked for me. If I execute
sudo -iu executerroot screen -dmS test bash -c "bash /home/pi/FileServer/Run; exec bash"
I get this:
bash: /home/pi/FileServer/Run/: No such file or directory
while it doesn't work for real files. When I type "screen -r" I get just blank bash screen if a file exists.
I can't figure out why it doesn't work. Please explain why it happens and how can I solve this.
Thanks...

After years, I got a similar problem today. This time I was trying to call the screen program inside crontab. I realized I needed absolute paths and correct bash version in crontab as well as in the script itself.
I think I had done a similar mistake 6 years ago. I wrote similar program today, probably, due to different environment variables, script didn't be able to find programs (in my case openvpn). Even program &> output.txt didn't work. The problem was the different bash version not supporting output redirection. I used /usr/sbin/bash -c "command" to cope with it. Also, openvpn is not in the path in that crontab environment, so I had to call it with absolute path (like /usr/sbin/openvpn). Then, it worked.

Related

Bash script for setting up mac keeps skipping commands or simply prints to the console without executing lines

I've been trying to create a bash script that allows me to transfer my existing dev setup to a brand new macbook.
I set up a bash script which is supposed to automate this process but for some reason when I call the script using curl, it doesnt seem to reliably run the whole thing and I cant figure out why that is. example of commands being printed to the console and note executed
If I were to manually enter each line into the terminal and execute, things work as expected however doing so defeats the purpose of the script.
I'll attach some screenshots of the terminal output so you can see the exact issues I'm facing and at which point it behaves oddly.
I've had to run the script a few times to get it to execute the skipped steps but it would be good to understand why certain steps are getting missed. Here's a link to my gist containing the script. Would appreciate any suggestions for improvements or explantations for the behaviour I'm seeing.
Things I have tried that havent resolved my issue:
Splitting the script into two smaller scripts
Erasing my mac and running the script again (done this several times)
Adding sleep 5 between each command
edit: this is how I'm running the script
sudo curl -Lks https://gist.githubusercontent.com/curtis-j-campbell/b695513a44393c3a5084c011c6d0c890/raw | /bin/bash
Thanks in advance
It appears that everything after brew install git is being echoed. That suggests that something in that command is copying its stdin to stdout, so it's processing the rest of the script. Change that line to
brew install git </dev/null
so it won't read the script as its stdin.
Also, you don't need to run curl under sudo. If you need privileges to install the program, you should run bash as the superuser, not curl.
curl -Lks https://gist.githubusercontent.com/curtis-j-campbell/b695513a44393c3a5084c011c6d0c890/raw | sudo /bin/bash

Run a Bash Script automatically upon login on Unix

I have a bash script that I've written that works if I execute from the terminal, but I want to be able to have this script ran when I login to my system. I have seen other questions similar to this, but the proposed solutions did not work for me. I tried adding the script path to my ~/.profile and the script still is not being ran. Anyone have an example or documentation on how to do this?
Side note I am using Unix
If you already had a ~/.profile file it should be fine to just add it there. Otherwise look for a ~/.bash_profile and add the line there.
Did you make sure that your file is executable? Otherwise it will not work.
Here is an example code (make sure to adapt to your needs):
echo "echo 'foo'" > /tmp/execute_me
chmod u+x /tmp/execute_me
echo "/tmp/execute_me" >> ~/.profile
login from another console (for safety), and you should see "foo" printed in your console somewhere.
If you want your script to be executed whenever a shell is used (even not interactive, you should add the code to the ~/.bashrc, read this for details: https://unix.stackexchange.com/questions/129143/what-is-the-purpose-of-bashrc-and-how-does-it-work)
The script should be called .profile and in your scripts directory.
I don't if your system supports it, but calling scripts (as root or as a common user , via su - user -c "command") from /etc/rc.local works great on my "nix" system. You might want to add some delay and possibly pass the display variable as well. Example of rc.local entry:
sleep 20 && bash -c "env DISPLAY=:0.0 nohup /folder/script &"

SSH heredoc to run Perl script on another server can't find right paths

I have a Perl program on server_B which uses Perl DBI and 5.010 and runs fine from the server_B terminal. I run it from a shell script which first prepares some arguments and then passes them to the Perl program, all works fine.
I need to run a shell script on server_A that will execute that script on server_B. This is because the Perl program creates several files that I want to SFTP back over to server_A. This is the script I'm running on server_A:
ssh server_B <<- EOF
perl/update.sh
EOF
There is some strange behavior which I'm trying to understand:
The script (update.sh) on server_B runs mysql, which is not installed on server_A (which is why I have to do this whole thing.) If I try to run it on server_B as-is, I can call mysql just like that. But when I run the above script (on server_A) to ssh into server_B and run that script, it doesn't recognize mysql unless I change the file (on server_B) to call the full path /opt/mysql/client/bin/mysql (even though that file is already on server_B with mysql installed) Does this mean server_B is picking up on the PATH variable from server_A instead of using my PATH variable from server_B? Is it trying to run my programs from server_A on the files on server_B? How and why??
If I make the change above it executes the script, but when it hits Perl it says
Perl v5.10.0- required - this is only v5.8.8
Again, 5.10 works fine on server_B but the version of Perl on server_A is 5.8.8.
So I got rid of use 5.010; because it actually wasn't necessary, but then I have a similar problem with my modules (DBI and DBD::mysql). I get:
Can't locate DBI.pm in #INC (#INC contains.. [my Perl PATH from server_A])
at perlfile.pl line 4
I was expecting the ssh heredoc call to update.sh (from server_A) to run exactly as update.sh does if I call it on server_B, but instead it seems like it's trying to use my programs from server_A on server_B, which I find weird. Can anyone help me understand why it's happening? I feel like I'm misunderstanding something fundamental about how ssh works.
server_A is AIX with ksh
server_B is AIX with bash
Edit - since some of you voted to the effect that I haven't done my research, here's what else I've tried. I didn't mention because I don't understand them fully, these are just guesses based on other SO posts & hunches. It'd be disingenuous if I gave the impression I knew what I was talking about.
If this is a duplicate, which question should I be looking at? If this is a "just read the manual situation", which one? What should I look for?
Read man ssh looking for clues related to environment variables, didn't find anything I understood
Tried running with -t
Tried running with -t -t
Did log in remotely with ssh and manually running it - this DOES work
Sourced my .bash_profile in the update script
Tried to re-assign PATH as the remote server's PATH when ssh
Tried using a different delimiter for the heredoc
Tried < instead of <<
Tried without the "-"
Edit 2 with Saigo's help below I determined that when in interactive ssh, if I echo $PATH I do get the target server's $PATH, but in a shell script I don't. That led me to this:
https://serverfault.com/questions/643333/different-bash-path-variables-when-using-ssh-script-vs-interactive-ssh
where I found out that scripted ssh doesn't call .bashrc, but interactive ssh does. So it looks like I was on the right track trying to source .bash_profile inside the scripted SSH heredoc, just need .bashrc not .bash_profile - however I don't have a .bashrc on the target server. I do have .profile but when I source that, I get an error stating it's for interactive bash sessions only. So now I'm just trying to find whatever file would contain my $PATH variable because it's apparently not .bashrc as there isn't one in there.
Edit 3 - tried hard-coding the PATH variable into a file and sourcing that and even then when I echo $PATH I get the origin server's PATH variable. It is reading the file in correctly, I also assigned another test variable and echoed that as part of the script. I tried sourcing /etc/profile and no luck.
I found a solution that works perfectly. I wasn't able to get it to work with ~/.bashrc, ~/.bash_profile, or ~/.ssh/rc but still not sure why it's not picking up my environment variables even with sourcing these.
Since it works when I manually ssh in and then run the commands one-by-one, I used these arguments to run ssh in a forced interactive login.
ssh server_B bash --login -i "~/perl/update.sh"
See these for more:
https://superuser.com/questions/564926/profile-is-not-loaded-when-using-ssh-ubuntu
https://unix.stackexchange.com/questions/46143/why-bash-unable-to-find-command-even-if-path-is-specified-properly
Hope this is useful for someone in the future. Thank you for your assistance Saigo.

What is wrong with this .command file?

This is my script to automate the git push of my static blog.
When I run each command one by one in the Terminal, it works. Do I need to add delays, maybe it's going too fast. The pelican command (static website generator) takes quite a lot of time (2 seconds). Is the rest of the script crashing during that?
#!/bin/sh
dropbox
cd blog
pelican . -s /Users/Paul-Arthur/Desktop/Desktop/Dropbox/blog/pelican.conf.py -t subtle
cd output
git add .
git commit -m 'commit'
git push
Updated: Sorry, yeah dropbox is a custom command in my bash_profile (this is not the problem, it works I know ;) ).
Sadly, when I click my script, it executes (but does not work) extremely quickly so I cannot see the errors.
Here is the output from the calepin command. The errors are normal and I expect it to run with that. Do you think that this is the problem? If so what can I do?
familys-imac:blog Paul-Arthur$ pelican . -s /Users/Paul-Arthur/Desktop/Desktop/Dropbox/blog/pelican.conf.py -t subtle
ERROR: Skipping ./articles/aboutme.md: impossible to find informations about 'title'
ERROR: Skipping ./articles/static_sites.md: impossible to find informations about 'title'
familys-imac:blog Paul
It might be due to the « cd » command, since it's not a command, it is a builtin from the shell, and doesn't act like a command.
To debug it, try adding «pwd» command inside your script before and after the «cd» line, to be sure the working directory has change.
It could also be due to the shell you are using, in the shebang (first line of your script), you are using the /bin/sh script. Is it the good one ? When you do it in your shell, you are maybe using another like bash, dash, zsh etc.
To determine that, type that in your current shell :
which `echo $0`
You will get an answer like :
/bin/bash
or something like this. Use this in your shell script :
#!/bin/bash
And try again your script.
Good luck with your project.

Activating a VirtualEnv using a shell script doesn't seem to work

I tried activating a VirtualEnv through a shell script like the one below but it doesn't seem to work,
#!/bin/sh
source ~/.virtualenvs/pinax-env/bin/activate
I get the following error
$ sh virtualenv_activate.sh
virtualenv_activate.sh: 2: source: not found
but if I enter the same command on terminal it seems to work
$ source ~/.virtualenvs/pinax-env/bin/activate
(pinax-env)gautam#Aspirebuntu:$
So I changed the shell script to
#!/bin/bash
source ~/.virtualenvs/pinax-env/bin/activate
as suggested and used
$ bash virtualenv_activate.sh
gautam#Aspirebuntu:$
to run the script .
That doesn't throw an error but neither does that activate the virtual env
So any suggestion on how to solve this problem ?
PS : I am using Ubuntu 11.04
TLDR
Must run the .sh script with source instead of the script solely
source your-script.sh
and not
your-script.sh
Details
sh is not the same as bash (although some systems simply link sh to bash, so running sh actually runs bash). You can think of sh as a watered down version of bash. One thing that bash has that sh does not is the "source" command. This is why you're getting that error... source runs fine in your bash shell. But when you start your script using sh, you run the script in an shell in a subprocess. Since that script is running in sh, "source" is not found.
The solution is to run the script in bash instead. Change the first line to...
#!/bin/bash
Then run with...
./virtualenv_activate.sh
...or...
/bin/bash virtualenv_activate.sh
Edit:
If you want the activation of the virtualenv to change the shell that you call the script from, you need to use the "source" or "dot operator". This ensures that the script is run in the current shell (and therefore changes the current environment)...
source virtualenv_activate.sh
...or...
. virtualenv_activate.sh
As a side note, this is why virtualenv always says you need to use "source" to run it's activate script.
source is an builtin shell command in bash, and is not available in sh. If i remember correctly then virtual env does a lot of path and environment variables manipulation. Even running it as bash virtualenv_blah.sh wont work since this will simply create the environment inside the sub-shell.
Try . virtualenv_activate.sh or source virtualenv_activate.sh this basically gets the script to run in your current environment and all the environment variables modified by virtualenv's activate will be available.
HTH.
Edit: Here is a link that might help - http://ss64.com/bash/period.html
On Mac OS X your proposals seems not working.
I have done it this way. I'am not very happy with solution, but share it anyway here and hope, that maybe somebody will suggest the better one:
In activate.sh I have
echo 'source /Users/andi/.virtualenvs/data_science/bin/activate'
I give execution permissions by: chmod +x activate.sh
And I execute this way:
`./activate.sh`
Notice that there are paranthesis in form of ASCII code 96 = ` ( Grave accent )
For me best way work as below.
Create start-my-py-software.sh and pest below code
#!/bin/bash
source "/home/snippetbucket.com/source/AIML-Server-CloudPlatform/bin/activate"
python --version
python /home/snippetbucket.com/source/AIML-Server-CloudPlatform/main.py
Give file permission to run like below.
chmod +x start-my-py-software.sh
Now run like below
.start-my-py-software.sh
and that's it, start my python based server or any other code.
ubuntu #18.0
In my case, Ubuntu 16.04, the methods above didn't worked well or it needs much works.
I just made a link of 'activate' script file and copy it to home folder(or $PATH accessible folder) and renamed it simple one like 'actai'.
Then in a terminal, just call 'source actai'. It worked!

Resources