2

I want to know the use of . ./.profile whenever we execute cron jobs. I have seen many scripts having this included. The question is, what is the use and what if I don't add it?

Example:

00 1-22 * * 1-5 . ./.profile ; /global/u1/sie/rox/Scripts/Calls.ksh >/dev/null 2>&1
codeforester
  • 39,467
  • 16
  • 112
  • 140
Tushar Sharma
  • 2,839
  • 1
  • 16
  • 38

2 Answers2

3

. somefile is the POSIX-compliant equivalent to the bash builtin source: Running source somefile in bash, or . somefile in any POSIX-compliant shell, executes every command inside that script in that existing shell.

In terms of why this is useful in a crontab: cron runs with a very minimal environment -- it may not even have a PATH set, and is unlikely to have many other facilities. If your scripts depend on environment variables being present, it can be necessary to either specify them in the crontab or to source in (that is, execute in the existing shell) a script which defines them.

That said, I advise against this idiom:

  • .profile is used by login sessions -- sessions with a user interacting with the shell in real-time -- and folks intending to customize their interactive session's behavior are liable to make modifications without keeping scheduled jobs in mind.
  • It's not obvious by reading your crontab which environment variables ~/.profile will or won't set, and thus difficult to reason about the state of the environment.

Instead, you should set environment variables at the top of your crontab:

PATH=/bin:/usr/bin:/usr/local/bin
VARNAME=VALUE
# ...etc...

0 1-22 * * 1-5 /global/u1/sie/rox/Scripts/Calls.ksh >/dev/null 2>&1
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • i have 2 more scripts on same path and scheduled without using . ./.profile it still works fine. So is it a real bad practice if i am not specifying . ./.profile?? Or is it completely dependent on what script we have?? can you explain your answer in little easy words as i am new to it.thanks – Tushar Sharma May 31 '17 at 15:53
  • Briefly: I advise that you don't specify `. .profile` at all. It's a shortcut, but there are better ways to do what people who use it are trying to accomplish. – Charles Duffy May 31 '17 at 15:55
  • so in other words specifying it and not specifying it do not effect on script output it still works fine? – Tushar Sharma May 31 '17 at 15:57
  • That's not strictly accurate, but for a **strictly** accurate explanation you should read my full answer (and look up / research any parts you don't understand). – Charles Duffy May 31 '17 at 16:02
  • 1
    To take another attempt at a terse explanation: The only utility of sourcing `.profile` before executing a script in a subprocess is to set environment variables. Environment variables *can* impact how a script runs. However, good practice is for any environment variables that are necessary for a crontab to be put direct in the crontab, not sourced from `.profile`. – Charles Duffy May 31 '17 at 16:05
  • Another idea: [$0.02]place the source/. command in the shell script itself. This will ensure that no matter how the script is executed (via cron, via some other scheduling system, via command line by someone with the right variables set, via command line by someone with the wrong variables set (or missing)) it will always work as planned. And yes, you'll want to make sure the first line of the script invokes the correct shell, eg, #!/bin/ksh, again, to make sure script is executed under correct shell no matter how/where/when it's invoked. [/$0.02] – markp-fuso May 31 '17 at 16:28
  • @markp, I really advise against that -- it means your scripts are more tightly bound to the systems they were written on, more likely to have side effects from configuration changes made with interactive sessions in mind, and less likely to work elsewhere. At least with the OP's original code you only got environment variables, but if you source `~/.profile` directly in the final script, then you also get shell functions, aliases, settings, etc (doubly so if that `.profile` sources `~/.rc` or an equivalent). – Charles Duffy May 31 '17 at 16:29
  • @CharlesDuffy: yes and no; placing the source/. command in crontab has the downside that scripts written under different shells (sh, ksh, bash, csh, tcsh, etc) aren't guaranteed to run properly unless the user knows up front which shell each script is using; as for scheduled vs interactive, in the past I've seen way too many situations where individuals running a script don't have the correct environment set (eg, scripts are based on a set of assumed-already-set variables, aliases and functions) and updating the system environment isn't always an option when I (and my users) are not sys admins – markp-fuso May 31 '17 at 16:36
  • @CharlesDuffy [ran out of space] ... being tightly bound to a system hasn't been a problem for me (for 20+ years) since I always make sure I program in a shell that's available on all systems I work on (again, that's been **my** experience, ymmv) – markp-fuso May 31 '17 at 16:39
  • @markp, eh? Using *function* declarations from `.profile` inside scripts is almost the very definition of "making your scripts needlessly environment-specific", since at that point they won't even run for any other user. As for sh/ksh/bash/etc., failing to write `~/.profile` to baseline POSIX sh is doing it wrong -- using [t]csh, likewise. :) – Charles Duffy May 31 '17 at 16:56
  • @markp, and putting the source command in the crontab makes it run with `/bin/sh`, **not** with the interpreter the individual script uses, since cron itself runs `/bin/sh -c '...'` -- so, we get `/bin/sh -c '. ./.profile ; /run/another/script.ksh'` -- and then the shebang in `/run/another/script.ksh` is properly honored. – Charles Duffy May 31 '17 at 17:01
  • @CharlesDuffy re: function declarations ... not quite following your comment since I've had no/zero/none issues with other users running my scripts that include loading/running custom function declarations – markp-fuso May 31 '17 at 17:07
  • @markp, function declarations *from a file in your home directory*?! *My* home directory isn't readable to other users at all. – Charles Duffy May 31 '17 at 17:09
  • @markp, ...I don't have a problem with sourcing `somelibrary.bash` (`somelibrary.ksh`, `somelibrary.sh`, &c. as appropriate for the specific shell it's written to), but `.profile` is a different beast; it's personal, and typically written and maintained with interactive use in mind (often with ugly hacks like functions overriding `cd` with `rvm` hackery and whatnot). – Charles Duffy May 31 '17 at 17:11
  • @CharlesDuffy: thanks for the correction re: cron/source/sh-c though still relies on the person building the crontab file to know what environment file to load; also, still doesn't address users running the shell script at the command line who fail to load the correct environment beforehand; my preference is to totally encapsulate everything I need in the shell script without having to rely on the caller having the proper env set – markp-fuso May 31 '17 at 17:12
  • @markp, ...that's mostly a reasonable preference, **if** what you're encapsulating is reasonably universal. If you'd be asking folks to rewrite/modify the script when they bring it over to a different machine, not so much. – Charles Duffy May 31 '17 at 17:13
  • @CharlesDuffy re: function declarations and their host directory ... uh, no, no one has access to my home directory, but they do have access to group-readable directories; yes, I have personal/custom envs I use, and I have customized envs I use for group scripts – markp-fuso May 31 '17 at 17:16
  • @markp, sure, but at that point you're no longer talking about having scripts that source your `.profile`, which is the practice proposed in this question that I'm pushing back against. – Charles Duffy May 31 '17 at 17:18
  • @markp, ...I was explicit about that earlier: "Using *function* declarations from `.profile` inside scripts[...]"; not sure why you objected if you propose sourcing in libraries from a different location. – Charles Duffy May 31 '17 at 17:19
  • @CharlesDuffy obviously moving a ksh script to bash/csh/etc is going to require some rewrites (especially if programming has benefited from some shell-specific features); I tend to work with ksh(93) which I've found available on all hosts I've ever had to work on, with the one gotcha being that I occasionally have to update a couple lines of code in the deployment script to make sure the first/shebang line is updated to point to correct path to ksh(93) – markp-fuso May 31 '17 at 17:23
  • @CharlesDuffy I tend to update .profile to include conditionals to source the other resource files (variables, aliases, functions) so, .profile is all I ever have to source ... whether it's login/command-line or near the top of a shell script; as I've mentioned before ... haven't had a problem with this setup (for myself, for group/team members) for 20+ years :) – markp-fuso May 31 '17 at 17:27
  • @markp, ...if that works for your team members, it clearly does so only because they're modifying their own `.profile`s -- that is, modifying their environment to suit your scripts. As someone with seniority you can get away with that -- if Random Noob Intern tried it, on the other hand... – Charles Duffy May 31 '17 at 17:43
  • @CharlesDuffy nope, they're not modifying their own .profiles (heck some of them prefer csh/.cshrc); scripts access a group-readable .profile – markp-fuso May 31 '17 at 17:48
  • Why would you use the hidden-file `.profile` naming convention for a file others are expected to access? Anyhow -- I'm absolutely fine with that; I've tried to be very clear from the beginning that it's sourcing a file **from the user's home directory** to which I firmly object. – Charles Duffy May 31 '17 at 17:51
  • @CharlesDuffy and who is the user? in my line of work there's always a group-accessible user account; crontabs are scheduled under this group-accessible user account hence ~/.profile refers to the group-accessible user account; shell scripts, whether executed by a real-person user (in the group) or group-accessible user will always access the group-accessible user's .profile. my scripts are written so that I never have to worry about an external sourcing of the correct environment; anyhoo, getting way off track at this point ... – markp-fuso May 31 '17 at 18:09
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/145578/discussion-between-markp-and-charles-duffy). – markp-fuso May 31 '17 at 18:09
0

The profile files are the shell profiles, you can add code to it that will run as soon as the shell start up, ./profile is the profile file for Ksh and Bourne, /.bash_profile is for bash /.login is for Tcsh and Csh. When a script calls the profile it's because it needs something from it, i.e $path variables or even specific commands that it might not have access to. In this case, since cron doesn't have access to much since it runs in a minimal enviroment that script will pull the .profile because it depends on something that's in there.

More info here

and here

MrSanchez
  • 317
  • 4
  • 14