対話型bashサブシェルでPS1を簡単に変更する

対話型bashサブシェルでPS1を簡単に変更する

より長いプロセス中にユーザーにサブシェルを提供する必要がある状況があります。ユーザーに特別なサブシェルにあり、残りのプロセスを完了していないことを知らせるようにプロンプ​​トを変更したいと思います。これで私は欲しいものを手に入れることができると思いました...

echo "PS1='foo:'" | bash -i

しかし、行を入力すると、これは私が得る出力です。

me@mercury:~$ PS1='foo:'
foo:exit
me@mercury:~$ 

この問題を解決する簡単な方法はありますか?独自のカスタムbashrcを作成できますが、ユーザーの一般的なbash-shell設定を維持することをお勧めします。

答え1

bash -iプロセス置換を使用すると、次のように呼び出されたときにのみ存在する〜/ .bashrcをデフォルトで生成できます。

 bash --rcfile <(echo "PS1='foo: '") -i

答え2

~/.bashrcそれでも読みたくなく~/.bashrc設定されていないと仮定するには、$PROMPT_COMMAND次のトリックを使用できます。

PROMPT_COMMAND='PS1="foo: ";unset PROMPT_COMMAND' bash

rcファイルが設定されていても、他のアプローチが機能し、$PS1$PROMPT_COMMANDのように(zsh / bash / ksh93シェルで)実行できます。

(
  export IN_FD
  exec {IN_FD}<&0
  echo 'PS1="foo: "; exec <&"$IN_FD" {IN_FD}<&-' | bash -i
)

PS1="foo: "これはパイプ入力であり、これはbashstdinを生のstdinに切り替えるように指示します。

これはstderrにプロンプ​​トとコマンドラインを表示する副作用があります。以下を使用して問題を解決できます。

(
  export IN_FD ERR_FD
  exec {IN_FD}<&0 {ERR_FD}>&2 2> /dev/null
  echo 'PS1="foo: "; exec <&"$IN_FD" {IN_FD}<&- 2>&"$ERR_FD" {ERR_FD}>&-' |
    bash -i
)

ただし、これは起動ファイルから出力されるエラーメッセージ(存在する場合)を隠す副作用があります。

答え3

env PS1="foo: " /bin/bash --norc -i私の考えでは、このオプションを使用する方が良いと思います--rcfile。環境はドットファイルで上書きされずに保存され、PS1環境変数はシェルに入る前に設定されます。

呼び出し側プログラムが追加の権限を提供している場合は、制限付きシェルを開くことも検討できます。env PS1="foo: " PATH=$RESTRICTED_PATH /bin/rbash --norc -i必要な $RESTRICTED_PATH 値について。

または、事前に作成されたbashrcファイルがあります。

if [ -f /etc/bashrc ]; then
    source /etc/bashrc
fi
if [ -f ~/.bashrc ]; then
    source ~/.bashrc
fi
PS1="foo:"
PATH=$RESTRICTED_PATH

それから電話してください/bin/bash -rcfile ~/.bashrc.appsubshell -i

答え4

SiegeXに同意します(彼は私より一歩先にありました:))

この動作を説明してください。

Bashは、標準入力と出力が通常の端末の場合にのみ対話モードで起動されます。パイプラインに初期コマンドを入力しても、そうではありません。

この-cオプションを使用してコマンドを提供できますが、対話型モードも除外されます。

本当にユーザーrcを維持するには、rcfile文字列にいくつかのテスト/ソースステートメントをソースに追加し、~/.bashrcファイル/etc/bashrcが存在することを確認してください。

関連情報