2

In which order are the distinct steps of this bash command done:

(flock -n 9) 9> toto.txt

If I do only the subshell part:

(flock -n 9)

I get this result: flock: 9: Mauvais descripteur de fichier (Wrong file descriptor).

Hence, I would assume that the subshell spawn opens the file descriptor 9 first with (...) 9> toto.txt.

But If I do:

(ls -l /proc/$$/fd) 9> toto.txt 
total 0
lrwx------ 1 laurent laurent 64 déc.  16 00:24 0 -> /dev/pts/2
lrwx------ 1 laurent laurent 64 déc.  16 00:24 1 -> /dev/pts/2
lrwx------ 1 laurent laurent 64 déc.  16 00:24 2 -> /dev/pts/2
lrwx------ 1 laurent laurent 64 déc.  16 00:24 255 -> /dev/pts/2

The file descriptor 9 is not listed. Hence it seems that flock is responsible for opening it?

Can someone explain what are the steps and their order for the "handshake" between the inside of the subshell and the outside of it?

2
  • 2
    $$ expands to the parent shell's PID, not the subshell's. Use (ls -l /proc/$BASHPID/fd) instead of (ls -l /proc/$$/fd), and you'll see an entry for FD #9. Commented Dec 16, 2023 at 4:23
  • Thanks @GordonDavisson :) This is the tl;dr answer. I accepted Chris Davies answer which is more expanded :). Commented Dec 16, 2023 at 16:53

1 Answer 1

3

Contrast the following:

sh -c 'ls -l /proc/$$/fd' 9>/tmp/toto.txt
total 0
lrwx------ 1 chris chris 64 Dec 16 11:24 0 -> /dev/pts/0
lrwx------ 1 chris chris 64 Dec 16 11:24 1 -> /dev/pts/0
lrwx------ 1 chris chris 64 Dec 16 11:24 2 -> /dev/pts/0
l-wx------ 1 chris chris 64 Dec 16 11:24 9 -> /tmp/toto.txt

sh -c "ls -l /proc/$$/fd" 9>/tmp/toto.txt
total 0
lrwx------ 1 chris chris 64 Dec 16 11:24 0 -> /dev/pts/0
lrwx------ 1 chris chris 64 Dec 16 11:24 1 -> /dev/pts/0
lrwx------ 1 chris chris 64 Dec 16 11:24 2 -> /dev/pts/0
lrwx------ 1 chris chris 64 Dec 16 11:25 255 -> /dev/pts/0

( ls -l /proc/$$/fd ) 9>/tmp/toto.txt        # Your own example
total 0
lrwx------ 1 chris chris 64 Dec 16 11:24 0 -> /dev/pts/0
lrwx------ 1 chris chris 64 Dec 16 11:24 1 -> /dev/pts/0
lrwx------ 1 chris chris 64 Dec 16 11:24 2 -> /dev/pts/0
lrwx------ 1 chris chris 64 Dec 16 11:25 255 -> /dev/pts/0

In the first example the $$ belongs to the child shell. In the second, and also for your own case, the $$ is evaluated by the parent shell before command execution.

Now to answer your original question,

In which order are the distinct steps of this bash command done: (flock -n 9) 9> toto.txt

This is defined by POSIX:

  1. The shell reads its input from a file (see sh), from the -c option or from the system() and popen() functions defined in the System Interfaces volume of POSIX.1-2017. If the first line of a file of shell commands starts with the characters "#!", the results are unspecified.
  2. The shell breaks the input into tokens: words and operators; see Token Recognition.
  3. The shell parses the input into simple commands (see Simple Commands) and compound commands (see Compound Commands).
  4. The shell performs various expansions (separately) on different parts of each command, resulting in a list of pathnames and fields to be treated as a command and arguments; see wordexp.
  5. The shell performs redirection (see Redirection) and removes redirection operators and their operands from the parameter list.
  6. The shell executes a function (see Function Definition Command), built-in (see Special Built-In Utilities), executable file, or script, giving the names of the arguments as positional parameters numbered 1 to n, and the name of the command (or in the case of a function within a script, the name of the script) as the positional parameter numbered 0 (see Command Search and Execution).
  7. The shell optionally waits for the command to complete and collects the exit status (see Exit Status for Commands).
3
  • Thanks for your answer @ChrisDavies :). Regarding the typo you corrected, '$' was here because I thought it would help distinguish between the command and its result. I don't know what is the recommended way to quote bash command plus result. I'm ok with your correction :). Commented Dec 16, 2023 at 16:55
  • 2
    $( ... ) is valid shell syntax, and would have generated an error in your example. Generally I would recommend not including a prompt as it also makes it harder for people to copy and paste your commands while testing Commented Dec 16, 2023 at 17:12
  • Thanks for reminding me that :). I mostly use very basic shell syntax for my day to day computing. In case someone wonders what it does $(echo 'ls') and your link above with POSIX specification may help :). Commented Dec 17, 2023 at 18:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .