1

I'm not super familiar with exec. I was running through some tests and examples. I wanted to pass a command written in a file to it. I'm expecting that command to be run with exec just as if it were run directly on the commandline. Here's what I set up and tried:

[kellyry@ch12ldvela00 ~]$ cat exec_test
ls
[kellyry@ch12ldvela00 ~]$ cat exec_test | exec
[kellyry@ch12ldvela00 ~]$ cat exec_test | xargs exec
xargs: exec: No such file or directory
[kellyry@ch12ldvela00 ~]$ exec ls
exec_test            file2             file3
. . .          

Here's the weirdest part. Running the last line exec ls doesn't return. That is the terminal hangs and I can't communicate with it. I'm thinking this last problem could be an issue with Mobaxterm which I'm using to ssh in to the server.

  • 2
    Welcome to U&L! What are you trying to do with exec here? It's possible that you've misunderstood its purpose -- see eg. https://unix.stackexchange.com/questions/160429/how-does-exec-bash-builtin-work-internally . – JigglyNaga Mar 12 '20 at 16:21
  • I don't think that answers it. I edited my question with my expecatation. Judging from my reading of man for the command and going through a couple online examples such as: https://www.geeksforgeeks.org/exec-command-in-linux-with-examples/ made me believe I was using it correctly. Easily could be wrong. – user2183336 Mar 12 '20 at 16:27
  • 1
    You missed out the bash command that precedes the exec ls in that example. – JigglyNaga Mar 12 '20 at 16:32

1 Answers1

5

From the bash manpage:

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

If command is specified, it replaces the shell. No new process is created.

[...]

If command is not specified, any redirections take effect in the current shell, and the return status is 0.

pipe to exec

The first thing you tried was

cat exec_test | exec

This sends ls to exec on the standard input, not as an argument. exec is run with no arguments, and it has no redirections, so it does nothing.

If you wanted to run (or "execute") the command(s) in the file, that's not what exec is for. You can do that with source (or the abbreviation .):

source exec_test

pipe to xargs exec

The next thing you attempted

cat exec_test | xargs exec

exec is a bash built-in. It's only available within bash, so xargs can't find it to execute it.

exec in the main shell

Finally, you tried

exec ls

This ran ls, then hung the terminal. That's because, as documented, it replaced the shell process. Once ls has finished, there's no longer anything running in the terminal. (Some terminal emulators will close automatically at this point. Fortunately, yours did not close, so you could still see the output.)

The example you were trying to follow had an extra step:

bash
exec ls

This first starts a new bash, running as a child of the "top-level" one. The exec ls then replaces that shell, and exits. Then the parent shell resumes, so you're not left with a stuck terminal.

JigglyNaga
  • 7,886