Bash:ターミナルで大きなHTMLブロックをインタラクティブに入力し、変数に保存します。

Bash:ターミナルで大きなHTMLブロックをインタラクティブに入力し、変数に保存します。

これはとても簡単です。

#!/bin/bash
echo "What is your name?"
read name
echo "Your name is: $name"

しかし、名前ではなくネストされたタグとすべての特殊文字を含む大きなHTMLブロックを処理したい場合はどうすればよいですか? (対話型で貼り付けるブロック)

ターミナル入力を介してbashスクリプトを使用してHTMLコード全体のブロックを変数に保存するにはどうすればよいですか?

答え1

readread a lineを使用する代わりに、入力から直接読み取るために使用できますcat。これは以下で読む標準入力(通常はプロンプトに直接入力する場合は端末)次のように作成します。標準出力(またターミナル)。 Ctrl/D を使用して入力を終了します。

cat

より一般的な場合、catコマンドは引数としてリストされた他のファイルから読み取られます。標準入力指定しないと、すべての入力が次に記録されます。標準出力

これをプログラムに入れて、

#!/bin/bash
echo "What is your name?"
name=$(cat)
printf 'Your name is: "%s"\n' "$name"

この例では、出力は変数として送信されます$name

答え2

次のことを試してみてください。

read -r -d name <<-EOF

コードを挿入してください。好きなだけ多くの行を貼り付けることができます。EOFbare と入力して行を終了します。

答え3

一時ファイルの無効化について言及していないので、テキストエディタを使用する奇妙な解決策があります。

# Variables
INPUT_TEXT=
TEMP_FILE=temp.html

# Set default editor for the system as nano unless defined
# Hard-code if you can, more consistent usage and users cannot invoke any program they desire through environment variable
EDITOR="${EDITOR:=nano}"

# WARNING: This line here might be a security issue, as it exposes use of a text editor freely, even if you hard-code the editor.
# Get input in a subshell (that's the key part here)
# The &3,&1,&2 redirections are beyond my grasp, but it is said it swaps stdout and stderr. The end goal here is to get TUI interaction with the subshelled command (likely nano in this script).
$( ${EDITOR} $TEMP_FILE 3>&1 1>&2 2>&1 );

# If above subshell ran successfully and user exitted saving the file
if [ $? = 0 ] && [ -f $TEMP_FILE ];
then
  INPUT_TEXT=$(cat $TEMP_FILE);

  # Remove temporary file, only when actually created
  rm $TEMP_FILE;
fi;

echo "$INPUT_TEXT"

1行形式:

EDITOR=${EDITOR:=nano}; INPUT_TEXT=; TEMP_FILE=temp.txt; $($EDITOR $TEMP_FILE 3>&1 1>&2 2>&1); if [ $? = 0 ] && [ -f $TEMP_FILE ]; then INPUT_TEXT=$(cat $TEMP_FILE); rm $TEMP_FILE; fi; echo "$INPUT_TEXT"

編集:HTMLで具体的に作業したい場合は、構文強調表示を使用してそれに応じてファイル拡張子を設定できます。

答え4

代わりに、zshの行エディタ(zle)を使用しzshて入力に改行文字を含めることができる変数エディタをbash使用できます。vared

#! /bin/zsh -
text=
vared -p 'text: ' text
printf 'Got: <%s>\n' "$text"

テキストにリテラル改行文字を入力するには、+を入力するかAltEnter+が環境の他の項目にバインドされている場合は+を入力するか、+の後に+を入力します。 (+は改行文字または文字を送信し、キャリッジリターンまたはキャリッジリターンとも呼ばれます。)zshシェルプロンプトと同じです。EscEnterAltEnterCtrlVCtrlJCtrlJ^J\nEnter^M\r

Enterテキストを別々に送信してください。

bindkey '^M' self-insert-unmeta呼び出す前にリテラル改行を入力するように追加し、ユーザーが+を使用してテキストを送信できるようにすることができます(または他のキーまたはキーの組み合わせをここにバインド)。varedEnterCtrlJaccept-line

zleサポートのおかげで複数の端末エミュレータは、括弧で囲まれた貼り付け機能をサポートし、デフォルトで有効にします。、そこに複数行のテキストを貼り付けることができる必要があります。角かっこ貼り付けを有効にできない場合、ターミナルエミュレータは通常貼り付けると「を」に変換するため、上記のように再バインドすると^M機能します。\n\r

セキュリティ上の理由から、ターミナルエミュレータは多くの制御文字を貼り付けることを許可しておらず、それを許可するように設定しても、一部の制御文字(SIGINT、SIGTSTPなど^C^Zはttyデバイスから傍受され、SIGINT、SIGTSTP信号を送信します。 。ただし、これはHTMLテキストには問題ありません。


bashread -eユーザーからテキストを読むには、対応する行エディタを使用する必要があります。bash行エディタ(readline)を使用すると、Ctrl+Vと改行文字を使用してCtrlテキストを入力することもできますJ

したがって、次のようにすることができます。

IFS= read -e -rd $'\r' -p 'text: ' text
printf 'Got: <%s>\n' "$text"

^Mテキストに文字を挿入することはできません。 bash変数にはNUL文字を含めることができないため、-d ''代わりにNULまで読み取って+を使用して-d $'\r'テキストを送信できます。CtrlSpaceEnter

readline角かっこの貼り付けもサポートされ、最新バージョンでもデフォルトで有効になります。以前のバージョンでは、以下を追加できます。

set enable-bracketed-paste`

ターゲット~/.inputrcまたは追加:

bind 'set enable-bracketed-paste' 2> /dev/null

呼び出す前にスクリプトにread


あるいは、moreutils 'を使用して、vipeテキスト入力のためにユーザーが好むエディタを実行できます。

text=$(vipe</dev/null)

vipeがない場合は、zsh次のことができます。

(){
  ${VISUAL:-${EDITOR:-vi}} $1
  text=$(<$1)
} =()

末尾の改行を削除する作業に注意してください。


プリセットは、次のすべての方法を使用して実行できます。

text=seed; vared -p 'text: ' text
IFS= read -e -rd $'\r' -i seed -p 'text: ' text
text=$(echo seed | vipe)
(){
  ${VISUAL:-${EDITOR:-vi}} $1
  text=$(<$1)
} =(echo seed)

さらに、read -e最初のソリューションを除くすべてのソリューションは対話型でのみ機能します。echo some text | those-scriptsたとえば、あなたはそれを行うことはできません。ただし、stdinが端末から出ていることを確認し、text=$(cat)そうでない場合は利用可能なチェックを追加できます。

if [ -t 0 ]; then
  # stdin is a terminal, use any of the solutions above
else
  text=$(cat)
fi

関連情報