プロンプトにsshfsマウントポイントが反映されますか?

プロンプトにsshfsマウントポイントが反映されますか?

リモートフォルダをローカルコンピュータにリモートでマウントするために使用しています。sshfs問題は、local誤ってリモートフォルダに害を及ぼすのを防ぐために、ローカルコンピュータのリモートフォルダの上または下で作業していることを知る方法が必要であることです。

私が現在リモートマウントポイントにあることをzsh / bashプロンプトに反映してより慎重に作業を行うにはどうすればよいですか?

例:sshfsでCDを実行すると、次のようにマウントされたフォルダlocal_of_remote_mountpointというメッセージが表示されます。sshfsuser@host: sshfs% ls

答え1

ここでは、2つの異なる問題に直面しています。

  1. 現在の作業ディレクトリ(PWD)がsshfs次にマウントされたファイルシステムに存在することを確認するには:
  2. シェルプロンプトでポイント1を反映する方法。

現在の作業ディレクトリがマウントされているファイルシステムの一部ですかsshfs

PWDを取付点と比較することは信頼できません。たとえば、そのコンポーネントがマウントポイントへのシンボリックリンクである場合、PWDは機能しない可能性があります。

GNU / Linuxでは、df同じツールを使用してディレクトリがあるfindmntマウントポイントを決定できます。また、両方でFSTYPE設定されたファイルシステムの属性を報告することもできます。fuse.sshfssshfs

したがって、以下を確認できます。

# df always prints a header line, we want to skip it
[ "fuse.sshfs" = "$(df --output=fstype . | tail -n +2)" ] && ...

または:

[ "fuse.sshfs" = "$(findmnt --noheadings --output=FSTYPE --target .)" ] && ...

このテストをスクリプトにラップしてから利用可能にすることができますPATHcheck_sshfs_mp

#!/bin/sh
[ "fuse.sshfs" = "$(findmnt --noheadings --output=FSTYPE --target .)" ] && exit 0
exit 1

現在のマウントポイントに基づいてシェルプロンプトをどのように設定しますか?

bashどちらもデフォルトのプロンプトに展開されるシェル変数をzsh設定できます。PS1

bash関連関数の周りのラッパーでこれを行うことができます:cd、、pushdpopdクレジット:「条件付PS1」への回答ありがとうございますcd私だけではないことを思い出してください。次のコードを次の項目に追加してください~/.bashrc

cd () { builtin cd "$@" && chpwd; }

pushd () { builtin pushd "$@" && chpwd; }

popd () { builtin popd "$@" && chpwd; }

chpwd () {
    normal='\[\e[0m\]'
    red='\[\e[1;31m\]'
    PS1='[\u@\h \W]\$ '
    if command -v check_sshfs_mp > /dev/null 2>&1; then
        check_sshfs_mp && PS1='[\u@\h '"$red"'R'"$normal"' \W]\$ '
    fi
}

関数は、終了状態があると赤い文字をchpwd呼び出してcheck_sshfs_mp追加します。必要に応じてデフォルト値を調整する必要があります。0RPS1
PS1

現在の作業ディレクトリが変更されるたびに特別な機能が実行されるzshため、やや簡単です。 (注:Zシェルマニュアル、zshchpwd特殊機能)。一緒に実行されるフック機能の配列にプロンプ​​ト設定機能を追加できますchpwd
使わないと仮定するとユーザー貢献干渉プロンプト設定に次のコードを追加できます~/.zshrc

chpwd_check_sshfs_mp () {
    PS1='%m%# '
    if command -v check_sshfs_mp > /dev/null 2>&1; then
        check_sshfs_mp && PS1='%m %F{red}R%f %# '
    fi
}
chpwd_functions+=( chpwd_check_sshfs_mp )

今回もR成功すると、デフォルトのプロンプトに赤を追加します。chech_sshfs_mp

端末を実行しているPWDがマウントされたファイルシステムにある場合、cdフック機能をラップして追加してもプロンプトが正しく設定されていることを確認できません。正しいプロンプトをトリガーするには、少なくともaが必要です。これは誤解を招く可能性があります。chpwd_functionssshfscd

zsh実行プロンプトのトピックへのユーザー貢献には、次のものが必要です。アドホックカスタムプロンプトのソリューションです。
次のコマンドを使用してプロンプトトピックをオフにできます。

prompt off

このコードを試してみましょう。


コメントで提起された重要事項を統合しますzsh

プロンプトの色を指定する場合ANSIエスケープシーケンス(カラー名の代わりに)上記のPS1スニペットの割り当て行を次のように変更できます。

check_sshfs_mp && PS1="$(print '%m %{\e[1;31m%}R%{\e[0m%} %# ')"

または

PS1='%m'"$(check_sshfs_mp && print '%{\e[1;31m%} R %{\e[0m%}')"'%# '

sは実際のエスケープ文字に変換する必要がprintあり、プロンプトコードで誤動作を防ぐためにその形式を使用する必要があります。参考資料:よくある質問:\e%{...%}zshcolor xtermでカラーヒントを取得する方法は?

デフォルトのプロンプトが設定されるたびに確認を実行するには、フック機能を追加せずにchpwd_functions次の項目に追加します.zshrc

setopt PROMPT_SUBST
export PS1='%m$(check_sshfs_mp && print "%{\e[1;31m%} R %{\e[0m%}")%# '

PROMPT_SUBSTこのオプションは、プロンプト表示でコマンド置換を有効にするために必要です。引用:急速な拡張Z Shell マニュアルにあります。

答え2

@fra.sanが提案したように、LOCALプロンプトを調整して、PS1使用されているパスのフォルダを反映するように変更できますsshfs

まず、端末がカラーヒントをサポートしていることを確認してください。~/.kshrc年には以下を含めてください~/.bashrc

# Option is turned off by default to not distract the user.
force_color_prompt=yes

if [ -n "$force_color_prompt" ]; then
    if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
    # you have color support; assume it's compliant with Ecma-48
    # (ISO/IEC-6429). If support lacks use `setf` rather than `setaf`.
        color_prompt=yes
    else
        color_prompt=""
    fi
fi

次に、ラッパーを使用してローカルFSにリモートボリュームをマウントするたびに、マウントされたリモートボリュームへsshfs_wrpのパスが一時ファイルに自動的に追加されます。たとえば、/tmp/tmp_rem_volsshfsコマンドの単純なラッパーを使用してこれを実行できます。

#!/usr/bin/sh
# script name: sshfs_wrp   # wrapper for sshfs
mount_path="$( echo "$@"| cut -d" " -f $# )"  # usually last parameter to `sshfs`
# Note: above will break when parameters passed to sshfs_wrp 
# contain blanks between quotes. 
echo "$mount_path" >> /tmp/tmp_rem_vol
sshfs "$@" 
exit 0

スクリプトが実行可能であり、PATH環境変数を介してその場所にアクセスできることを確認してください。

~/.kshrc次に、文字列が以前にを使用してマウントされたリモートボリュームサブツリーで現在作業中であることを示す場合は、~/.bashrcフラグ変数を設定するためまたは関数を定義します。携帯性のため使用しています。remFlag[R]"$(pwd)"sshfs_wrpcase
編集する: caseパターン一致部分で一致が見つかった場合は、whileループを終了する必要があります。

function check_rem_vol () {
    if [ -s /tmp/tmp_rem_vol ] ; then
        while read rem_vol; do
            case "$(pwd)" in 
                # check whether pwd contains sshfs_wrp-mounted volume 
                *"${rem_vol}"*) remFlag="[R]" ; break  ;;  
                *) remFlag="" ;;
            esac
        done < /tmp/tmp_rem_vol
    else
        remFlag=""
    fi
    echo "$remFlag"
}

PS1最後に、~/.kshrcyrのyrプロンプトを変更するか、yrを使用して一部のリモートボリュームがマウントされている場合は、明るい緑色で表示されるように、プロンプトにリモートボリュームフラグを~/.bashrc含めて変更します。rem_volsshfs_wrp

if [ "$color_prompt" = yes ]; then
    # For Debian based systems only
    #PS1="${debian_chroot:+($debian_chroot)}\[\e[0;38;5;166m\][\#/\!]\[\e[1;34m\] \w\[\e[38;5;46m\] \$(check_rem_vol)\[\e[1;38;5;166m\]>\[\e[0m\]"

    # For Archlinux
    PS1="\\[\\e[0;38;5;166m\\][\\#/\\!]\\[\\e[1;34m\\] \\w\\[\\e[38;5;46m\\] \$(check_rem_vol)\\[\\e[1;38;5;166m\\]\\> \\[\\e[0m\\]"
else
    # For Debian based systems only
    #PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
    #PS1="${debian_chroot:+}[\#/\!] \[\w \$(check_rem_vol)\]>"

    # For Archlinux
    PS1="[\\#/\\!] \\[\\w \$(check_rem_vol)\\]>"
fi
export PS1
unset color_prompt force_color_prompt

/tmp/tmp_rem_vol複数のSSH接続が共存し、リモートボリュームが別のリモートホストからマウントされている場合は、可動部分の数を減らし、一時ファイルまたは複数の一時ファイルの作成を改善するようにソリューションを改善できます。

bashこれはDebianまたはArch Lxプラットフォームまたはシェル内のSSH接続で機能します。ksh

/tmp/tmp_rem_volまた、リモートボリュームのマウント解除、セッションのログオフ、SSH接続のクローズ時に永続性の問題を回避するには、消去に注意する必要があります。また、これを自動化するための多くの参考資料やヒントもあります。

ファタイ

関連情報