3

I need a way to test whether input to my Bash script has been piped to stdin when the script is run in batch mode. The method I use when I run the script interactively (the test [ -p /dev/stdin ]) fails in batch mode. Specifically, it fails in PBS but not SLURM batch queues. I need a method that works interactively (connected to a terminal) and in batch mode with both PBS and SLURM.

The "-p /dev/stdin" test yields unexpected results in PBS batch mode. The test below shows that a program expects data from a pipe to stdin whenever the program executes in batch mode, even though the script creates no such pipe. This implies PBS does something special (besides disconnecting it from the terminal) with stdin when in batch mode. Whatever the reason, this behavior violates the premise that a batch job will behave like an interactive job called the same way. And this behavior causes my scripts to crash in PBS in batch mode.

The same test executed in the SLURM environment behaves as expected, and reports no stdin pipe unless the user creates one.

Is there a cross-platform solution that works interactively, and in both PBS and SLURM? As the attached script shows, the test [ ! -t 0 ] is not what I need either.

Charlie

cat > ~/inp_std.sh << 'EOF'
#!/bin/bash
if [ -p /dev/stdin ]; then
    printf "[ -p /dev/stdin ] is true\n"
else
    printf "[ -p /dev/stdin ] is false\n"
fi # !stdin
if [ ! -t 0 ]; then
    printf "[ ! -t 0 ] is true\n"
else
    printf "[ ! -t 0 ] is false\n"
fi # !stdin
EOF
chmod 755 ~/inp_std.sh
cat > ~/inp_std_tst.sh << 'EOF'
#!/bin/bash
echo foo > ~/foo
printf "No pipe, no re-direction: ~/inp_std.sh\n"
~/inp_std.sh
printf "Pipe to stdin:            echo hello | ~/inp_std.sh\n"
echo hello | ~/inp_std.sh
printf "Redirection to stdin:     ~/inp_std.sh < foo\n"
~/inp_std.sh < ~/foo
EOF
chmod 755 ~/inp_std_tst.sh
qsub -A CLI115 -V -l nodes=1 -l walltime=00:30:00 -N inp_std -j oe -m e -o ~/inp_std.out ~/inp_std_tst.sh
qsub -A arpae -l walltime=00:30:00 -l nodes=1 -N inp_std -q batch -j oe -m e -o ~/inp_std.out ~/inp_std_tst.sh
sbatch -A acme --nodes=1 --time=00:30:00 --partition=debug --job-name=inp_std --mail-type=END --output=${HOME}/inp_std.out ~/inp_std_tst.sh

Results with PBS:

zender@rhea-login4g:~$ more ~/inp_std.out
No pipe, no re-direction: ~/inp_std.sh
[ -p /dev/stdin ] is true
[ ! -t 0 ] is true
Pipe to stdin:            echo hello | ~/inp_std.sh
[ -p /dev/stdin ] is true
[ ! -t 0 ] is true
Redirection to stdin:     ~/inp_std.sh < foo
[ -p /dev/stdin ] is false
[ ! -t 0 ] is true

Results with SLURM:

zender@edison05:~> more ~/inp_std.out
Running with ~/inp_std.sh:
[ -p /dev/stdin ] is false
[ ! -t 0 ] is true
Running with echo hello | ~/inp_std.sh:
[ -p /dev/stdin ] is true
[ ! -t 0 ] is true
Running with ~/inp_std.sh < foo:
[ -p /dev/stdin ] is false
[ ! -t 0 ] is true

Note how the first line of the PBS results differs from the SLURM results for the exact same script.

  • I have run into similar issues when pipelining several short commands into one another that depend on reliably determining if `stdin` is a pipe or not. – 111--- Aug 15 '18 at 21:15

0 Answers0