RE: Placing the full pathname of the job stdout in an environment variable Would others find it useful if new variables were added that contained the full pathnames of the standard input, error and input files of batch jobs?
## SYNOPSIS Proposed new environment variables SLURM_STDOUT,SLURM_STDERR, and SLURM_STDIN pointing to the full pathnames of the output, error output, and input files of a task would be a useful feature for batch jobs in particular. ## PROBLEM There are cases where it is desirable to have a job process the standard files (stdin, stdout, stderr) from a batch job from within the job instead of later via an epilog or via post-processing. Just a few examples where the job might want to reference the full pathname of stdout: * copy the file to a remote machine (via scp(1), for example) * move the file from local or scratch space to permanent globally accessible storage * remove the file depending on completion status * mail the output * archive it * post-process it Slurm commands like scontrol(1) and squeue(1) can help you locate the file names. But the names returned do not always expand all the macros allowed when specifying the names, and require calling a Slurm command (which might overload Slurm if millions of jobs are submitted or cause problems if Slurm is not responding for any reason(?)). For example: #!/bin/bash # Minimalist submit script for sbatch(1) #SBATCH --nodes 1-1 --ntasks=1 --time 0-0:1:00 --chdir=/tmp #SBATCH --output=stdout.%j #SBATCH --error=stderr.%A:%a:%J:%j:%N:%n:%s:%t:%u.out # query filenames via squeue(1) export SLURM_STDOUT=$(squeue --noheader --Format=STDOUT: --job=$SLURM_JOBID) export SLURM_STDERR=$(squeue --noheader --Format=STDERR: --job=$SLURM_JOBID) # PS: Current documentation for squeue(1) does not explicitly tell the # user a null size works. # query filenames via scontrol(1) declare -x $(scontrol show job=$SLURM_JOBID|grep StdOut) declare -x $(scontrol show job=$SLURM_JOBID|grep StdErr) cat <<EOF SLURM_STDOUT=$SLURM_STDOUT SLURM_STDERR=$SLURM_STDERR StdOut=$StdOut StdErr=$StdErr EOF ls stdout.* stderr.* The resulting output shows either none or some macros are expanded by the commands (and I am not sure all commands will always return a full pathname(?)) SLURM_STDOUT=/home/urbanjs/venus/V600/stdout.%j SLURM_STDERR=/home/urbanjs/venus/V600/stderr.%A:%a:%J:%j:%N:%n:%s:%t:%u.out StdOut=/home/urbanjs/venus/V600/stdout.96 StdErr=/home/urbanjs/venus/V600/stderr.96:4294967294:%J:96:%N:%n:%s:%t:urbanjs.out stderr.96:4294967294:96:96:mercury:0:4294967294:0:urbanjs.out stdout.96 One currently available work-around would be that the user just avoid the filename macros and always specify the filenames using a standard convention (which would obviously have to be specific to a specific platform). This is error-prone as it requires the user to strictly follow a protocol where the pathnames are specified that can be overridden by command-line options on sbatch(1) and so-on. Alternatively instead of the new environment variables Slurm could have a command option that returns the fully expanded names always expanding the macros. But if you query Slurm you have to worry about scaleability. Is it OK for a 100 000, jobs to query Slurm simulataneously via squeue(1) or scontrol(1)? What happens if for external reasons the Slurm daemons are down or not responding? As a current work-around using commands like realpath(1), stat(1), ls(1),find(1),and getting pids with fuser(1), pidof(1), and ps(1) become attractive. I find using the realpath(1) command at the top of the job and $SLURM_TASK_ID works the best. realpath(1) may not be available on all platforms(?) as well as the /proc/$PID/fd/1 file, in which case the other commands might be used to the same effect but it would be nice to have a simple standard way that does not require calling a command. The proposed environment variables seem the most obvious solution. # do this early in the job in case the user changes or closes # file descriptor 1 ... export SLURM_STDOUT=$(realpath /proc/$SLURM_TASK_PID/fd/1) # create softlink OUTPUT to stdout of job ln -s -f $SLURM_STDOUT OUTPUT # now user can do things like mailx(1) or scp(1) the OUTPUT file. Other reasons I might want to know the stdout pathname are to minimize network traffic and filespace on central servers. I might specify the output of a job goes to scratch or local storage or a memory-resident file system and move it all to a location on another system or a long-term archive instead of a central area that might be filled by other jobs or that I have a quota on, etc. So since the stdout might not be easily accessible from my other sessions also having something like "scontrol write batch_stdout=$SLURM_JOBID" that shows the stdout of the job would also be useful. Note the LSF job scheduler bpeek(1) command allows for a tail(1)-like interface to the job stdout to support the stdout not being accessible from all system access points, just as described. The current situation where in typical usage the output file is often in a globally mounted area and I can just access it from other nodes with grep(1), tail(1), and so on covers many users needs in simple cluster configurations; but there are several scenarios as described above primarily encountered by people running many thousands of single-node jobs where assigning output to a local scratch device and then selectively processing at job termination is preferable. As mentioned, those users can specify such a local name with "#SBATCH --output" and then, knowing it, process it as desired but having something like $SLURM_STDOUT being the full pathname to the file is much more generic. ## SUMMARY So adding the variables creates an ability for users to reliably access the standard files of a job with a low-load scalable method; and being a SLURM_* module it could be much more reliably accessed via prolog and epilog scripts and module(1) scripts as well. ## PS: Related to this would be instead of just --chdir a --mkdir and --scratch #SBATCH option would be useful that expanded file macros that would be similar to --chdir but would make sure the directory existed (using only user privelages) and a --scratch that would do the same as --mkdir but remove the directory at job termination. urbanjs@mercury:~/SLURM/proposals$ Sent with [Proton Mail](https://proton.me/) secure email.