私は次の機能を持っています:
#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
この場合、ve
関数( "vim andexit" == "ve")は2番目の二重引用符で呼び出されます(ここを参照:)gcc -S $fname.c; ve $fname.s ;exec bash
。問題は、bashがエラーを発生させbash: ve: command not found
(export
見てわかるように、後でわかりました)、これをより明確にするために何をすべきかわかりません。
2回目の試みでは、以下を試しました。
#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
つまり、コマンドをサブシェルにしますが、開こうとすると ->Vim: Warning: Output is not to a terminal
ターミナルがクラッシュします。もしそうなら、問題はグローバル関数を二重引用符で囲んで安全にすることです。
答え1
最初のソリューションは私のシステムで完全に機能します。
他のシステムでテストしてみてください。システムに問題がある可能性があります。
2番目の例では、以下を強制的にvim
使用できます/dev/tty
。
ve() { vim "$@" </dev/tty >/dev/tty || exit; }
答え2
Xubuntuでこれを試してみると、xfce4-terminalは実際に新しい端末ウィンドウを実行するために新しいプロセスを起動しないようです。代わりに、既存のプロセスを呼び出して作成します。別のウィンドウから始まるシェルは、すべて同じxfce4端末プロセスの子プロセスです。
これは、関数を渡すために使用された環境変数が最初のシェル(関数をエクスポートしたシェル)のサブシェルではないため、新しいシェルに渡すことができないことを意味します。実行中のxfce4-terminalコピーがないと、新しいプロセスが開始され、環境変数が正常に渡されます。あるいは、例えばxtermを実行すると、常に新しいプロセスが作成されます。
これはコメントにリンクされているKusalalanandaの質問と似ていますが、異なります。グラフィカルログイン時に.profileから機能をエクスポートする方法しかし、同じ解決策が動作します。
~/.bashrc
代わりに、ここで始まるシェルが読み取る必要がある関数定義をその中に入れてください。それ以外の場合は、内部シェルで明示的にこれを行う必要がありますbash -c '. ~/.bashrc; gcc ...'
。
2番目のスニペットでは:
xfce4-terminal --tab -e "bash -c "\""gcc -S $fname.c; $(ve $fname.s) ;..."
コマンド置換は二重引用符で囲まれているため、xfce4-terminalが開始される前にここで拡張されます。したがって、正しくエクスポートされているかどうかに関係なく実行されます。コマンド置換内で動作してもコンパイラの前に実行されるため、目的の操作は実行されません。