-2

From Bash Manual

exec [-cl] [-a name] [command [arguments]]

If command is supplied, it replaces the shell without creating a new process.

If the -l option is supplied, the shell places a dash at the beginning of the zeroth argument passed to command. This is what the login program does.

If -a is supplied, the shell passes name as the zeroth argument to command.

Without -l or -a what is in the zeroth argument passed to command?

What is the purpose of -l placing a dash at the beginning of the zeroth argument?

What is the purpose of -a passing name as the beginning of the zeroth argument?

I tried to experiment. Why does the first experiment not output anything, while the second outputs bash?

$ bash; exec echo $0 

$ bash; 
$  exec 'echo' $0 
bash
  • I get "bash" output in both of your examples; is that your actual session output? What do you mean by "without -l or -a what is the ... argument ... like" ? It it like an elephant, or is it like a string or it like a bunch of bytes? What are we comparing it to? Would strace output clarify your understanding? – Jeff Schaller Jul 31 '17 at 23:15
4

Without -l or -a what is the zeroth argument passed to command like?

In this case the zeroth argument is just command itself.

What is the purpose of -l placing a dash at the beginning of the zeroth argument?

It's a convention that most (all?) shells respect. When a login session is started, the shell is started with a hyphen in front of its zeroth argument (placed there by login or whatever launched the session) and the shell interprets this as a signal to start a new login session.

What is the purpose of -a passing name as the beginning of the zeroth argument?

It's the only way of setting a zeroth argument that is [substantially] different from the pathname or filename that was used to actually start the process. The reason you might want to do this is that a few commands check their zeroth argument to see how they should behave. You can also use this to fool a program into thinking it was launched from a different pathname than it actually was (this might help it find its data files, for example).

$ bash; exec echo $0

This is a bit of a strange command. The echo will certainly output something (and then immediately terminate your session), but not until the subshell that you launch first terminates. What exactly are you trying to test/achieve here?

If you wanted to test the functionality, you'd do:

$ strace -fe execve bash -c 'exec -a foo echo test'
execve("/bin/bash", ["bash", "-c", "exec -a foo echo test"], [/* 56 vars */]) = 0
execve("/bin/echo", ["foo", "test"], [/* 56 vars */]) = 0
test
+++ exited with 0 +++
$ strace -fe execve bash -c 'exec -l echo test'
execve("/bin/bash", ["bash", "-c", "exec -l echo test"], [/* 56 vars */]) = 0
execve("/bin/echo", ["-echo", "test"], [/* 56 vars */]) = 0
test
+++ exited with 0 +++
$ (exec -a uname busybox)
Linux
$ (exec -l bash -c 'echo "$0"')
-bash
$ (exec -l ksh -c '[ -o login ] && echo yes')
yes

(with exec -l bash -c ... (or bash -lc ...), bash does read the ~/.bash_profile, but otherwise doesn't consider itself a login shell).

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