1

screen対話型シェルから呼び出された場合にのみセッションを開始する(または既存のセッションに再参加する)シェルスクリプトを設定しようとしています。私が見た解決策$-は、文字「i」が含まれているかどうかを確認することです。

#!/bin/sh -e

echo "Testing interactivity..."
echo 'Current value of $- = '"$-"
if [ `echo \$- | grep -qs i` ]; then
  echo interactive;
else
  echo noninteractive;
fi

ただし、これは失敗します。これは、スクリプトが#!/bin/sh、上部の結果として呼び出される新しい非対話型シェルによって実行されるためです。スクリプトを実行する代わりにソースを作成すると、希望どおりに機能しますが、それは醜いハックです。私はそれを実行するときにむしろそれを動作させたいです。

では、スクリプト内の対話性をどのようにテストできますか?

4

6 に答える 6

1

これを試してみて、探しているものが実行されるかどうかを確認してください。

#!/bin/sh
if [ $_ != $0 ]
then
  echo interactive;
else
  echo noninteractive;
fi

アンダースコア($_)は、スクリプトの呼び出しに使用される絶対パス名に展開されます。ゼロ($0)は、スクリプトの名前に展開されます。それらが異なる場合、スクリプトはインタラクティブシェルから呼び出されました。Bashでは、の後続の展開により$_、前のコマンドに展開された引数が与えられます(値$_を保持するために、の値を別の変数に保存することをお勧めします)。

差出人man bash

   0      Expands to the name of the shell or shell script.  This  is  set
          at shell initialization.  If bash is invoked with a file of com‐
          mands, $0 is set to the name of that file.  If bash  is  started
          with  the  -c option, then $0 is set to the first argument after
          the string to be executed, if one is present.  Otherwise, it  is
          set  to  the file name used to invoke bash, as given by argument
          zero.
   _      At shell startup, set to the absolute pathname  used  to  invoke
          the  shell or shell script being executed as passed in the envi‐
          ronment or argument list.  Subsequently,  expands  to  the  last
          argument  to the previous command, after expansion.  Also set to
          the full pathname used  to  invoke  each  command  executed  and
          placed in the environment exported to that command.  When check‐
          ing mail, this parameter holds the name of the  mail  file  cur‐
          rently being checked.
于 2010-07-12T23:42:17.737 に答える
1

$_おそらく必須で動作しますが、すべてのPOSIX互換shで動作するとは限りません。

$PS1シェルがインタラクティブである場合にのみ設定されます。したがって、これは機能するはずです。

if [ -z "$PS1" ]; then
    echo noninteractive
else
    echo interactive
fi
于 2010-07-22T13:19:35.533 に答える
0

試すtty

if tty 2>&1 |grep not ; then echo "Not a tty"; else echo "a tty"; fi

man tty:ttyユーティリティは、標準入力に接続されている端末の名前を標準出力に書き込みます。書き込まれる名前は、ttyname(3)によって返される文字列です。標準入力が端末でない場合は、「ttyではありません」というメッセージが書き込まれます。

于 2010-07-14T08:41:17.213 に答える
0

あなたは次のようなものを使ってみることができます...

if [[ -t 0 ]]
then
     echo "Interactive...say something!"
     read line
echo $line
else
     echo "Not Interactive"
fi

テストフィールドの「-t」スイッチは、指定されたファイル記述子が端末と一致するかどうかをチェックします(たとえば、出力が端末に出力される場合は、これを実行してプログラムを停止することもできます)。ここでは、プログラムの標準入力が端末と一致するかどうかを確認します。

于 2010-07-15T20:02:25.117 に答える
0

簡単な答え:``または。内でこれらのコマンドを実行しないでください[ ]

ここでは、これらの構成のいずれも必要ありません。


明らかに、あなたが何を期待していたのかわかりません

[ `echo \$- | grep -qs i` ]

テストすることですが、あなたがテストしていると思うものをテストしているとは思いません。

そのコードは次のことを行います。

  • サブシェル内で実行しますecho \$- | grep -qs i( ``のため)。
  • サブシェルの標準出力をキャプチャします。
  • 元の``式をその出力を含む文字列に置き換えます。
  • その文字列を引数として[コマンドまたは組み込み(シェルによって異なります)に渡します。
  • その文字列が空でない場合にのみ、正常なリターンコードを生成し[ます(文字列がオプションのように見えなかったと仮定します[)。

考えられる問題:

  • -qsオプションを使用すると、出力が生成されないため、どのように見えるかに関係なく、空の文字列をテストすることをgrep期待します。[$-
  • バックスラッシュがドル記号をエスケープして、リテラルの「ドルマイナス」(変数の内容ではなく)をに送信している可能性もありますgrep

一方、[バックティックとバックティックを削除して、代わりに

if echo "$-" | grep -qs i ; then

それから:

  • 現在のシェルは"$-"、テストする値で拡張されます。
  • echo ... |grep標準入力でそれを送信します、
  • grepその入力に文字が含まれている場合、正常なリターンコードが返されますi
  • grep-qsフラグが原因で出力が出力されない、および
  • ifステートメントは、の戻りコードを使用しgrepて、どのブランチを取るかを決定します。

また:

  • バックティックは、コマンドが実行されたときに生成された出力に置き換えられることはありません。
  • の戻りコードを、によって生成された出力からそれ自体で再構築しようとし[た戻りコードに置き換えようとするコマンドはありません。grepgrep

ifコマンドの使用方法の詳細については、優れたBashGuideのこのセクションを参照してください。

于 2013-10-01T12:59:45.360 に答える
0

$-外部プロセス(例)をフォークせずにの値をテストする場合はgrep、次の手法を使用できます。

if [ "${-%i*}" != "$-" ]
then
    echo Interactive shell
else
    echo Not an interactive shell
fi

i*これにより、の値から一致するものがすべて削除$-され、違いが生じたかどうかが確認されます。


${parameter/from/to}コンストラクト(たとえば[ "${-//[!i]/}" = "i" ]、インタラクティブな場合はtrue)はBashスクリプトで使用できますが/bin/sh、DebianおよびUbuntuシステムにあるDashには存在しません。)

于 2013-10-01T13:20:00.527 に答える