11

I'm migrating some software from Unix to Linux.

I have the following script; it is a trigger of a file transfer.

What do the exec commands do?

Will they work also on Linux?

#!/bin/bash
flog=/mypath/log/mylog_$8.log
pid=$$
flog_otherlog=/mypath/log/started_script_${8}_${pid}.log

exec 6>&1
exec 7>&2
exec >> $flog
exec 2>&1


exec 1>&6 
exec 2>&7

/usr/local/bin/sudo su - auser -c "/mypath/bin/started_script.sh $1 $pid $flog_otherlog $8" 

The started script is the following:

#!/bin/bash
flusso=$1
pidpadre=$2
flogcurr=$3
corrid=$4
pid=$$

exec >> $flogcurr
exec 2>&1

if  [ $1 = pippo ] || [ $1 = pluto ] || [ $1 = paperino ]
    then
        fullfile=${myetlittin}/$flusso
        filename="${flusso%.*}"
        datafile=$(ls -le $fullfile  | awk '{print $6, " ", $7, " ", $9, " ", $8 }')
        dimfile=$(ls -le $fullfile  | awk '{print $5 " " }')
        aaaammgg=$(ls -E $fullfile  | awk '{print $6}'| sed 's#-##g')
        aaaamm=$(echo $aaaammgg | cut -c1-6)
        dest_dir=${myetlwarehouse}/mypath/${aaaamm}
        dest_name=${dest_dir}/${filename}_${aaaammgg}.CSV
        mkdir -p $dest_dir
        cp $fullfile $dest_name
        rc_copia=$?
fi

I will change ls -le into ls -l --time-style="+%b %d %T %Y" and ls -E into ls -l --time-style=full-isoand in Linux.

11
  • 4
    Note that the exec redirect syntax is not a linux thing, it's a sh / bash thing and will work the same on all bourne shell based shells.
    – user10489
    Dec 28, 2021 at 15:04
  • 4
    BTW, the code you inherited is not great -- there are tons of places where it has quoting-related bugs, f/e. Consider running it through shellcheck.net and fixing the issues identified. And also see the "Getting Metadata On Files" section of Why you shouldn't parse the output of ls. Dec 29, 2021 at 16:53
  • 1
    Another note: /usr/local/bin/sudo su - auser -c "/mypath/bin/started_script.sh $1 $pid $flog_otherlog $8" has some serious security problems. I would write this as two commands, one that generates a safely-escaped command to run and a second one that runs it: printf -v args '%q ' "$1" "$pid" "$flag_otherlog" "$8" and then sudo su - auser -c "/mypath/bin/started_script $args" Dec 29, 2021 at 16:57
  • 1
    ...otherwise if someone passed something like $'$(rm -rf ~)\'$(rm -rf ~)\'' (or code that downloads and runs a rootkit, or so forth) in a place where it got substituted into $1 or $8 or so forth, you would have a very bad day. (I don't know the context of this script, but if it handles uncontrolled content like uploaded files, that's extra dangerous). Dec 29, 2021 at 16:59
  • 1
    @CharlesDuffy They are files transmitted from one office to another office of the same company. Anyway, I'll follow your advice.
    – CarLaTeX
    Dec 29, 2021 at 17:00

2 Answers 2

10

exec [n]<&word will duplicate an input file descriptor in bash.

exec [n]>&word will duplicate an output file descriptor in bash.

See 3.6.8 in: https://www.gnu.org/software/bash/manual/html_node/Redirections.html

The order of arguments can be confusing, though.

In your script:

  • exec 6>&1 creates a copy of file descriptor 1, i.e. STDOUT, and stores it as file descriptor 6.

  • exec 1>&6 copies 6 back unto 1.

    It could also have been moved by appending a dash, i.e. 1<&6- closing descriptor 6 and leaving only 1.

In between, you'll usually find operations that write to STDOUT and STDIN, e.g. in a subshell.

Also see: Practical use for moving file descriptors

1
  • it doesn't seem to matter if you use <& or >&. The documentation does say for e.g. <& that "If the digits in word do not specify a file descriptor open for input, a redirection error occurs", but I can't get that error. With a recent-ish devel version of Bash, exec 9>foo.txt; exec 8<&9 works fine (and fd 8 is left open for writing only, cat <&8 gives an error etc.)
    – ilkkachu
    Dec 28, 2021 at 15:59
5

exec {number x}>&{number y} copies file descriptor X into Y.

File descriptors usage:

  • 0 = stdin
  • 1 = stdout
  • 2 = stderr
  • 3-9 = additional file descriptors

In your case, they should have been opened somewhere earlier with something like exec 3<> /tmp/some_file to set fd3 to to some file.

Usually, you can do exec 2>&1 in order to redirect stderr output into stdout.

Your bash example is not complete, as $8 referrs to the eight argument given to your script, so there's definitly something we're missing here like arguments 2-7...

7
  • I think it is something set by the file transfer when it starts the trigger. The script Iposted is exactly the one that runs, I only changed the name of the paths, started scripts and logs.
    – CarLaTeX
    Dec 28, 2021 at 14:41
  • Pretty sure /mypath/bin/started_script.sh uses those file descriptors later Dec 28, 2021 at 14:42
  • Yes, exactly. I'll add the started_script.sh to my question in a while.
    – CarLaTeX
    Dec 28, 2021 at 14:45
  • Added (the interesting part of it).
    – CarLaTeX
    Dec 28, 2021 at 14:51
  • 2
    or rather, exec x>&y copies fd y into fd x.
    – ilkkachu
    Dec 28, 2021 at 15:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.