1

I have these function:

#execute vim and then exit on err return
ve() {
    vim "$@" || exit
}
export -f ve

#compile c source -> asm source in new tab in xfce terminal
casm() {
  [ -z ${1} ] && return
  fname=$1
  xfce4-terminal --tab -e "bash -c "\""gcc -S $fname.c; ve $fname.s ;exec bash \""
}
export -f casm

In this case, the ve function ("vim and exit" == "ve"), is called in the second one in double quotes (see here:gcc -S $fname.c; ve $fname.s ;exec bash). The problem is the bash will give err bash: ve: command not found (I have export it afterwards, as you can see), I do not know what else I should do to make it more visible.

For second try, I have tried this:

#compile c source -> asm source in new tab in xfce terminal
casm() {
  [ -z ${1} ] && return
  fname=$1
  xfce4-terminal --tab -e "bash -c "\""gcc -S $fname.c; $(ve $fname.s) ;exec bash \""
}
export -f casm

That is - make the command to be subshell, but then when trying to open it -> Vim: Warning: Output is not to a terminal, which makes it to crash the terminal. So the question is, how to embed a global function in double quotes and make it safe?

3
  • In the second, the command substitution is in double quotes, so it gets expanded before xfce4-terminal runs. It looks like the function doesn't end up in the inner shell at all. I don't know why xfce4-terminal or anything should clean it out from the environment, but if it was there, you shouldn't get "command not found" for it
    – ilkkachu
    Commented Jun 2, 2020 at 18:29
  • Your goal is not clear to me, but if the problem is related to the double quotes after -e, consider using -x instead.
    – Quasímodo
    Commented Jun 2, 2020 at 19:35
  • Possibly related to unix.stackexchange.com/questions/505358/… (the terminal emulator, or a shell spawned by it may clean up the environment and delete the exported functions before running the bash -c script).
    – Kusalananda
    Commented Jun 2, 2020 at 19:44

2 Answers 2

0

Your first solution works flawlessly on my system.

Try testing it on another system: You may have something broken on your system.

In the second example, you can force vim to use /dev/tty:

ve() {     vim "$@" </dev/tty >/dev/tty || exit; }
1
  • But this somehow breaks the ability to open the file in new tab (which it did before, with the xfce4-terminal --tab ...), is it different to use ` </dev/stdin >/dev/stdout`? or does /dev/tty means the same?
    – Herdsman
    Commented Jun 2, 2020 at 18:37
0

Trying this on Xubuntu, it seems like xfce4-terminal doesn't actually start a new process to run the new terminal window. Instead, it just calls on the existing process to create it. The shells I started in different windows were all children of the same xfce4-terminal process.

This means that the environment variables used to pass the function along can't be passed to the new shell, as it's not a child of the first one, the one where you exported the function. If you don't have a copy of xfce4-terminal running, then it does start a new process and the environment variables get passed ok. Or, if you run e.g. xterm instead, since it always creates a new process.

This is similar to but different from the issue Kusalananda linked in the comments, How to export functions from .profile during graphical login, but the same solution should work:

Put the function definition in ~/.bashrc instead, it should get read by the shells started here. If not, then you'll have to do it explicitly in the inner shell bash -c '. ~/.bashrc; gcc ...'.


In your second snippet:

xfce4-terminal --tab -e "bash -c "\""gcc -S $fname.c; $(ve $fname.s) ;..."

The command substitution is in double quotes, so it's expanded right here and now, before xfce4-terminal is launched. So, regardless of if it's exported properly, it runs. Though even if it worked from inside the command substitution, it wouldn't do what you want since it would run before the compiler.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .