バッシュから脱出

バッシュから脱出

テキストメッセージが表示されたら、プログラムでbashコマンドを生成して端末エミュレータを開き、このテキストを表示する必要があります。
たとえば、HelloWorld入力文字列の場合は、次の出力文字列を返す必要があります。
gnome-terminal -e "$SHELL -c echo\ HelloWorld;exec\ $SHELL"

問題は、入力メッセージに任意の記号を含めることができることです。
試行錯誤により、私は異なるシンボルを異なる時間にエスケープする必要があることを決定しました。

"A" must be converted to "A"        (0 times to be escaped)
" " must be converted to "\ "       (1 times to be escaped)
"(" must be converted to "\\\("     (2 times to be escaped)
"\" must be converted to "\\\\\\\\" (3 times to be escaped)

たとえば、\(o o)/次のようにコマンドに挿入する必要があります\\\\\\\\\\\(o\ o\\\)\\\/gnome-terminal -e "$SHELL -c echo\ \\\\\\\\\\\(o\ o\\\)\\\/;exec\ $SHELL"

実際、私はbashをまったく知らないので、その論理を完全に理解していません。
一般的な規則、つまりASCIIサブセット(10,32-126)のシンボルを変換する方法を教えてください。

編集する:
私がやっていることのより明確なアイデアを提供します。

文字列InputTextを受け取り、別の文字列、つまり正しいbashコマンドを返す関数(一部のプログラミング言語)を作成しようとしています。
現在私はこの関数を次の簡単な接続で実装しようとしています。
1) 定数接頭辞gnome-terminal -e "$SHELL -c echo
2) InputText に依存する内部部分
3) 定数接尾;exec\ $SHELL"
辞の問題は内部部分にあります。変換後、各InputTextシンボルを連結して計算しようとしています。しかし、任意のシンボルを変換する方法がわかりません。

編集2:
バルクエスケープを避けるために一重引用符を使用するというアイデアをいただいたchoraに感謝します。
私はbashについて多くを学びました。 ))

これは chorobの答えの修正版です。
同じアイデアですが、「バックスラッシュ - バックスラッシュ接続」はなく、Luaで実装されました。

function run_terminal(text)
   local function q(s) return "'"..s:gsub("'","'\\''").."'" end
   os.execute(
      'gnome-terminal -e "$SHELL -c "'..q(q("echo "..q(text)..";exec $SHELL"))
   )
end
run_terminal "Some Text"

編集3:
gnome-terminalの「-x COMMAND」オプションに言及したGillesに感謝します。このオプションには引用は不要であるため、ビルドコマンドで引用レベルを下げることができます。

function run_terminal(text)
   local function q(s) return "'"..s:gsub("'","'\\''").."'" end
   os.execute("gnome-terminal -x sh -c "..q("echo "..q(text)..";exec $SHELL"))
end
run_terminal "Some Text"

答え1

文字列を引用するには、バックスラッシュを使用して引用します。 2回引用する場合は、両方の参照タイプをエスケープする必要があります。

修正する:Gnome端末には三重引用符が必要です。文字列内の単一引用符を2回エスケープし、挿入された文字列の周囲に単一引用符を使用します。また、元の文字列のバックスラッシュをバックスラッシュする必要があります。

証明:私は次のPerlスクリプトを使用しました:

#!/usr/bin/perl
use strict;
use warnings;
use feature qw{ say };

chomp( my $msg = <> );
$msg =~ s/\\/\\\\/g;           # Quis backslashies backslashes tandem?
$msg =~ s/'/'\\''/g for 1, 2;  # Replace ' by '\'' twice.
$msg =~ s/"/\\"/g;             # Backslash double quotes.
system q(gnome-terminal -e 'bash -c "echo '\\'') . $msg . q('\\''; exec bash"');

答え2

引用符を忘れて、テキストを環境変数に入れてください。

-xシェルを起動するために使用されます。

これにコードを書かないでください$SHELL。どの構文を理解しているかわかりません。コードを実行しsh$SHELL対話型シェルを呼び出すために呼び出されます。

message='HelloWorld' gnome-terminal -x sh -c 'printf %s\\n "$message"; unset message; exec "$SHELL"'

関連情報