1

Does a terminal emulator execute a program always indirectly via shell?

For example, when we open a terminal emulator window, it automatically executes a shell, and we can only type commands in the shell.

For example, when running a program directly on a terminal emulator, such as

xterm -e "echo hello; sleep 5"

Does xterm execute the program, indirectly via shell, or directly without shell?

slm
  • 369,824
Tim
  • 101,790

3 Answers3

4

It depends on the terminal emulator.

xterm will first call execvp(2) with the arguments given to -e, but if that fails and there is a single command argument following -e, it will also try $SHELL -c command.

mlterm and rxvt will just error out if the execvp fails.

If my second paragraph didn't convince you, you can try this:

$ mkdir /tmp/tbin; ln -s /usr/bin/vi '/tmp/tbin/echo hello; sleep 5'
$ PATH=$PATH:/tmp/tbin xterm -e 'echo hello; sleep 5'

Or look at the source.

2

With your example, using the -e option, then xterm will start a shell, the manual states this.

It is possible to override xterm's default search for a shell, so you could supply your own program for this, but when you override the shell you cannot use the -e option. When you override the shell, then the your shell is run (fork() + exec()) directly by xterm.

Here are the relevant sections,

One  parameter  (after all options) may be given.  That overrides xterm's built-in choice of
shell program.  Normally xterm checks the SHELL variable.  If that is not set,  xterm  tries
to  use  the  shell  program specified in the password file.  If that is not set, xterm uses
/bin/sh.  If the parameter is not a relative path, i.e., beginning with “./” or “../”, xterm
looks for the file in the user's PATH.  In either case, it constructs an absolute path.  The
-e option cannot be used with this parameter since it  uses  all  parameters  following  the
option.

and

-e program [ arguments ... ]
   This option specifies the program (and its command line arguments) to be run in the
   xterm window.  It also sets the window title and icon name to be the basename of the
   program being executed if neither -T nor -n are given on  the  command  line.   This
   must be the last option on the command line.

And just looking at what you are executing,

"echo hello; sleep 5"

It's the shell which parses that string, it uses the PATH env variable to find the two commands, and realises that it is indeed two commands separated with the semi colon, xterm doesn't do that!

X Tian
  • 10,463
0

According to the manual, you can disable login shell with parameter +ls:

   +ls     This option indicates that the shell that is started should not
           be a login shell (i.e., it will be a normal “subshell”).

So xterm -e "echo hello" spawns a shell, but xterm +ls -e "echo hello" does not.

Ipor Sircer
  • 14,546
  • 1
  • 27
  • 39
  • xterm +ls -e "echo hello" executes echo hello indirectly by a shell, doesn't it? – Tim Nov 28 '18 at 00:50
  • That is, xterm +ls -e "echo hello" executes a shell to execute echo hello, doesn't it? – Tim Nov 28 '18 at 00:59
  • 2
    You're confusing "login shell" vs. "non-login shell" with having a shell at all... xterm +ls -e '...' still runs a shell, just not a login shell. You can easily check that by running a command that needs the shell (like something with ;) or by using, say, ps -p $$ – filbranden Nov 28 '18 at 01:28