Shell script to use my login environment - shell

I have crontab running a shell script periodically. I need the script to run in the same environment that I usually log in. Can I just simply add this line in 2nd line of the script (after shebang).
source /home/<my username>/.cshrc
Or what's the proper way to set the cron shell process to use my login environment?
PS: I am quite sure which exactly setting is needed by my script, so I can only source the whole .cshrc.

Try something like that:
sudo su - <user> -c <cmd>
Of course you have to alter the sudoers file first.
Take a look at the man page.
hth

Related

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 &"

Raspbian: Reset Bash environment variables

I was trying to get a crontab working on my Raspberry PI and I think I messed up my environment variables. I can execute a file from the GUI by right-clicking and choosing execute. However I cannot get the same file to run from command line. I can use ls to see the file (ChromeTab.sh), but when I type ChromeTab.sh, I get "bash: ChromeTab.sh: command not found".
I think I messed up my environment variables when I put this in the crontab.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
I followed the examples in Script doesn't run via crontab but works fine standalone.
Any idea what I'm doing wrong?
UPDATE:
OK,
Let me clarify what efforts I took on my part BEFORE posting my question on stackoverflow before getting anymore downvotes.
First of all thanks S. Adam Nissley for your suggestions.
In answer to your steps listed above.
Running this from home path, or fully qualified path does Not work as stated.
Error: bash: ChromeTab.sh: command not found
./ChromeTab.sh
I have also ensured read/write and execute permissions on the file with
chmod +x ./ChromeTab.sh
Also, my bash script starts off with the following shebang
#!/bin/sh
So, what i'm trying to say is, regardless of using crontab or not the issue at hand is that I can not even execute the script from command line. This started happening after I was messing around with the environment variables in the crontab. I'm looking for a way to revert to the situation where I can at least run/execute bash commands from the terminal.
The only way I can effectively execute this script is (right-click execute) through the GUI.
Assuming you are in the same directory as your script, you should just be able to enter
./ChromeTab.sh
If it does not execute, make sure it is executable with the command
chmod +x ./ChromeTab.sh
Or
chmod 755 ./ChromeTab.sh
And if it still won't execute, make sure it has an appropriate hashbang on the very first line of the script like #!/bin/sh or #!/bin/bash
When you add it to your crontab, make sure it has the full path like
/home/pi/bin/ChromeTab.sh <br/>
EDIT: Default PATH and SHELL for Raspbian
You can check your PATH and SHELL environmental variables from the command line as follows:
echo $SHELL
echo $PATH
The default PATH for Rasbian is:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games
And the default SHELL is:
/bin/bash
So if you need to set those it is as simple as:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games
SHELL=/bin/bash
If you are having other issues with your environment, you may want to disable some of your local settings to see if the problem is in your profile. You can list all files with ls -a, which includes hidden files. Raspbian typically has a .bashrc and a .profile in each user's home directory. To disable them simple rename them:
mv .bashrc .bashrc_disabled
mv .profile .profile_disabled
If that solves the problem, you can inspect the files and make the necessary corrections before renaming them back to their original names.

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.

Source a script remotly via ssh

I want to run a remote program via ssh which requires a certain environment. Thus before executing the program I source a specific file building up the environment. If I'm logged onto the machine directly this is no problem but when I execute the command via ssh
#!/bin/bash
foo=`ssh user#host "source ~/script.sh; ~/run/program"`
I get an error that indicates that the script was not sourced correctly. Do you know what I have to do in order to get the script sourced and the program executed in the same session?
EDIT:
I'm exporting the LD_LIBRARY_PATH with the script and the executable is complaining that it cannot find the shared object file. The default shell is bash. 'Session' is definitive not the right wording. I meant 'terminal environment'.
This may not be the cleanest way, but if you invoke bash with the interactive option (-i) and send commands through the standard input, it should work.
In particular,
foo=`ssh user#host bash -i <<EOF
source ~/script.sh
~/run/program
EOF`
It would be much easier if you have a script program_in_env.sh that does exactly the two steps you want:
#!/bin/bash
source ~/script.sh
~/run/program
Then you would just need to call ssh user#host program_in_env.sh.
Good luck.
Thank you for all your time and help. I found the issue. The basic idea of how to execute the remote program was right from the beginning. When testing my case locally on the machine, the current working directory was different. For some reason the cwd is important when sourcing this bash script.

How to autorun crons?

I'm trying to get a file to be automatically run by crontab, contents like so:
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
*/5 * * * * php /path/to/script
I've put this file called prod.cron into the /etc/cron.d folder but can't seem to get it to run on it's own. Running the script directly via command line shows that it works okay, but not sure if the files in cron.d get auto detected or do I need to do something else to init them?
Note that directory /etc/cron.d is intended to be used by packages, crontabs should be installed into an users crontab. That being said, check out the following Cron Issues:
The script is not having execute permissions. Use chmod a+x to provide permissions.
In the case of php, perl or other scripting language, the path to interpretor or program is not correct. Always provide actual path to
the interpretor while defining command to run in cron. To find out
where the program is located, use whereis command. For e.g.
for php, whereis php. for perl, whereis php, etc.
The environment variables required to run the script are unavailable. The cron doesn't use the same environment of a user. It
uses its own environment while running the commands. So the variables
defined in .login or .profile are not visible to him. The most common
issue is related to PATH variable which is not similar.
There are two flavors of cron file.
Files installed under /etc/cron.d are system cron files. They require the 6th field on each line to be the user account used to run the command. See other files under /etc/cron.d for examples.
Non-system cron files just have the usual 5 fields to specify when the job runs, followed by the command to run. They're installed by the crontab command, executed by the user account that will run the command(s). This is probably what you wnat to use.
Either add root as the 6th field of the relevant line, or run crontab prod.cron as root (or as whatever account should run the command).
And of course make sure the php command is in the specified $PATH.

Resources