1

NOTE: st is the actual name of the terminal emulator in my question - https://st.suckless.org/.


I want to create a shortcut that if pressed, pops up st and displays the translation of the word in the clipboard.

I tried using this, but is exits immediately and gives an error:

$ st -e "trans $(xclip -o) -t en; read"`
child finished with error '256'

But the same works with xterm just as expected:

$ xterm -e "trans $(xclip -o) -t en; read"

Using only one command as the -e option of st works, but I need to execute read or something like that after trans so the terminal won`t close immediately.

Is this a bug in st or am I doing something wrong?

  • Oh god another terminal - https://st.suckless.org/ – slm Aug 08 '18 at 10:31
  • It did actually already clarify that in the question title, @slm. – JdeBP Aug 08 '18 at 10:35
  • @JdeBP - I don't know if that's a euphemism or what. I've never heard of this terminal before in 30+ yrs. The project's about shows it as ~10yrs (2008). – slm Aug 08 '18 at 10:37
  • I have; and we've had questions dealing with it for over half that time. example example example – JdeBP Aug 08 '18 at 10:50
  • @JdeBP - 4 out of 145k is backing up my position 8-). I mean no disrespect to the project, I just hadn't ever heard of it, and assumed, perhaps incorrectly that others would be in the same boat as I. – slm Aug 08 '18 at 10:54
  • So did the questioner, which is why xe already explained what it was in the question title. (-: – JdeBP Aug 08 '18 at 11:27

2 Answers2

3

The -e option is a compatibility mechanism in simple terminal. The command and arguments that you pass, with or without -e, are executed directly, by simple terminal forking and then running execvp() in the child process on exactly the command and arguments it is given. There's no shell involved, and the arguments passed to st are sent on exactly as-is to the target program.

You have passed everything all as one argument. So simple terminal is actually trying to run a command named, literally, trans $(xclip -o) -t en; read (if single quoted, or that modified by whatever the result of the expansion is if you use double quotes). Obviously, you have no command named that.

To use a shell command line — such as you have here with expansions, shell built-in commands, and shell command syntax — you have to explicitly invoke a shell to understand it:

st -e sh -c 'trans "$(xclip -o)" -t en; read'

This runs st which starts an sh shell which runs a short shell script, which contains your commands.

JdeBP
  • 68,745
Kusalananda
  • 333,661
1

Looking at the man page for st:

st [-aiv] [-c class] [-f font] [-g geometry] [-n name] [-o iofile] [-T title] 
[-t title] [-l line] [-w windowid] [[-e] command [arguments...]]


-e command [ arguments ... ]
      st executes command instead of the shell.  If this is used it must be 
      the last option on the command line, as in xterm / rxvt. This option 
      is only intended for compatibility, and all the remaining arguments 
      are used as a command even without it.

I would agree with @Kusalananda that this switch is only intended to take a single command and nothing as complex as what you're trying to perform.

So for this you need to pass a shell in as the -e argument to st and then pass your commands in as a secondary set of arguments to the more capable shell:

$ st <other args> -e sh -c '....'
$ st <other args> -e bash -c '....'

References

slm
  • 369,824