現在のターミナルタブのタイトルを変更するスクリプトを見つけました:
#!/usr/bin/env bash
T=$1
ORIG=$PS1
TITLE="\e]2;$T\a"
PS1=${ORIG}${TITLE}
echo "Terminal tab title changed to $T"
ターミナルに直接入力するとうまく機能します(例TITLE="\e]2;HELLO\a"
:
しかし、シェル スクリプト (rename.sh) 内では $PS1 が空であり、スクリプトは機能しません。
rename.sh HELLO は出力されます"Terminal tab title changed to HELLO"
が、ターミナルのタイトルは変更されません。スクリプト内の $PS1 は空です。
誰かこれを理解するのを手伝ってくれませんか?
答え1
このスクリプトは、シェルの対話型プロンプトを、ウィンドウ タイトルを操作するための制御コードを含む文字列に設定することによって機能しますxterm
。シェルのプロンプトが表示されるたびに、ウィンドウ タイトルを変更するための制御コードが出力されます。
しかし、もちろん、スクリプト内では対話型プロンプトは表示されないため、これらのコマンドは目に見える効果はありません (ただし、スクリプト内から別の対話型シェルを起動すると、ウィンドウ タイトルの変更を確認できます)。また、スクリプトは親プロセスの環境を変更できないため、スクリプトが終了すると変更は失われます。
とにかく、スクリプトから、制御コードを直接印刷することもできます。
printf '\033]2;Hello\a'
これにより、ウィンドウのタイトルが一度変更されますが、後で他のプログラムが再度タイトルを変更すると、古いタイトルは失われます。プロンプトを変更するトリックは広く普及しています。これは、過去に人気のあったプログラムの中には、好みに合わせてウィンドウのタイトルを変更した直後に、そのタイトルを変更するものが多かったためです (ただし、これはもはや一般的な問題ではないと思います)。欠点は、ウィンドウのタイトルを変更する正当な理由がある場合、シェルがプロンプトを再度表示するとすぐに、そのタイトルが置き換えられてしまうことです。
現在のシェルのプロンプトを変更するコードが必要な場合、通常のスクリプトにそれらを入れることはできませんが、source
スクリプト ファイルを使用するか、代わりにシェル関数にコマンドを入れることができます (通常、永続化するために Bash プロファイルで行われます)。
ちなみに、Bash プロンプトには、プロンプトの表示幅を計算する際に、プロンプトの一部が実質的にゼロ幅であることを Bash に伝えるための追加の制御コードが含まれている必要があります。たとえば、長いコマンドを入力してからバックスペースが必要な場合、行の折り返しが不規則になることがわかります。Bash はプロンプトを再描画しようとしますが、画面制御コードがプロンプトの幅に関係していると判断して、間違った場所で再描画します。これらのコード\[
と、\]
その周囲に Bash 制御コードを追加する必要があります。
PS1="$ORIG\[$TITLE\]"
(中括弧は実際には何の役にも立たず、読みにくくなるため、削除しました。)
答え2
この変数はPS1
対話型シェルでのみ使用されるため、アクセスするにはスクリプトを で開始する必要がありますbash -i rename.sh
。
最小限の例:
$ echo 'echo $PS1' > test
比較する
$ bash test
$ bash -i test
スクリプトを実行可能ファイルとして直接実行するには、最初の行に次のコードを追加します。
#!/bin/bash -i
知らせこれは、 chmod を実行してスクリプトを直接実行した場合にのみ機能します (例: ./rename.sh
)。 では機能しません。bash rename.sh
それ以外の場合は、 を再度呼び出す必要がありますbash -i rename.sh
。
編集
ターミナルタイトルを直接変更するには、制御コードを直接エコーします。
echo -e '\033]2;SomeTitle\007'
またはスクリプト内で変数を使って
title="SomeTitle"
echo -e '\033]2;'$title'\007'