简体   繁体   中英

Multiple exec in a shell script

What happens if you have multiple exec commands in a shell script, for example:

#!/bin/sh

exec yes > /dev/null &
exec yes alex > /dev/null

I assume that a fork is still needed in order to execute the first command since the shell needs to continue executing?

Or does the & specify to create a sub process in which the exec is actually then run?

The use of & implie a sub-process.

So exec have no effect.

Demo:

export LANG=C
echo $$
17259
exec sh -c 'echo $$;read foo' &
[1] 17538
17538

[1]+  Stopped                 exec sh -c 'echo $$;read foo'   
fg

exec sh -c 'echo $$;read foo'  
17259

I run the script: echo $$;read foo in order to prevent exit before having quietly read previous output.

In this sample, the current process ID is 17259 .

When run with ampersand ( & ), the output is another pid (bigger). when run without ampersand, the new shell replace the command and is not forked .

Replacing the command by:

sh -c 'echo $$;set >/tmp/fork_test-$$.env;read'

re-running the whole test will generate two files in /tmp .

On my desk, I could read:

19772
19994
19772

So I found two files in /tmp :

-rw-r--r-- 1 user0 user0 2677 jan 22 00:26 /tmp/fork_test-19772.env
-rw-r--r-- 1 user0 user0 2689 jan 22 00:27 /tmp/fork_test-19994.env

If I run: diff /tmp/fork_test-19*env , I read:

29c29
< SHLVL='0'
---
> SHLVL='1'
46a47
> _='/bin/sh'

So the first run, with ampersand is in a sublevel .

Nota: This was tested under many different .

The shell forks to run the background process, but that means the new shell still needs to fork to run yes . Using exec eliminates the fork in the subshell.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM