AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 501789
Accepted
Tuyen Pham
Tuyen Pham
Asked: 2019-02-21 00:24:01 +0800 CST2019-02-21 00:24:01 +0800 CST 2019-02-21 00:24:01 +0800 CST

提示反映 sshfs 挂载点?

  • 772

我曾经sshfs将远程文件夹远程挂载到本地计算机,问题是我需要一种方法来知道我正在本地计算机上的远程文件夹或local文件夹下工作,以避免意外伤害远程文件夹。

如何让 zsh/bash 提示以反映我当前处于远程挂载点,以便我会更仔细地执行操作?

示例: sshfs now 当我 cd to 时local_of_remote_mountpoint,提示将通知我这是使用sshfs如下方式安装的文件夹:user@host: sshfs% ls

zsh arch-linux
  • 2 2 个回答
  • 355 Views

2 个回答

  • Voted
  1. Best Answer
    fra-san
    2019-02-22T05:37:16+08:002019-02-22T05:37:16+08:00

    我们在这里面临两个不同的问题:

    1. 如何知道当前工作目录(PWD)是否在由sshfs;挂载的文件系统上
    2. 如何在 shell 提示中反映第 1 点。

    文件系统的当前工作目录的一部分是由 安装的sshfs吗?

    将 PWD 与挂载点进行比较是不可靠的。例如,如果您的 PWD 的一个组件是一个挂载点的符号链接,它可能不起作用。

    df在 GNU/Linux 上,工具findmnt能够确定目录所在的挂载点。此外,两者都可以报告FSTYPE文件系统的属性,该属性设置fuse.sshfs为由sshfs.

    因此,您可以检查:

    # 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 .)" ] && ...
    

    您可以将此测试包装在一个脚本中,并使其在您的PATH. 在这里,我们将调用它check_sshfs_mp:

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

    如何根据我们所在的挂载点设置 shell 提示符?

    在两者中bash,zsh您都可以设置PS1shell 变量,该变量被扩展为主要提示。

    在bash您可以在相关功能的包装器中执行此操作:cd和pushd(popd感谢:感谢对“Conditional 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,如果其退出状态为0,则向 中添加一个红色R字母PS1。您可能需要根据自己的喜好
    调整默认值。PS1

    在zsh某种程度上更容易,因为只要当前工作目录发生更改,就会zsh执行特殊功能(参考:Z Shell 手册,特殊功能)。您可以将提示设置函数添加到与 一起执行的钩子函数数组中。 假设您没有使用干扰提示设置的用户贡献,您可以将此代码添加到您的:chpwdchpwd
    ~/.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和添加chpwd_functions挂钩函数将无法确保正确设置提示。sshfs您至少需要 acd来触发正确的提示,这可能会产生误导。

    用户对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%}')"'%# '
    

    请注意,print需要将\es 转换为实际的转义字符,并且%{...%}需要表单以避免提示代码行为不端。参考:zsh常见问题解答:如何在我的颜色 xterm 上获得彩色提示?

    如果您希望在每次设置主要提示时都执行检查,您可以避免将钩子函数添加到chpwd_functions并添加到您的.zshrc:

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

    需要该PROMPT_SUBST选项才能在提示显示中启用命令替换。参考: Z Shell 手册中的提示扩展。

    • 3
  2. Cbhihe
    2019-02-21T05:51:49+08:002019-02-21T05:51:49+08:00

    按照@fra.san 的建议,您可以通过调整来修改 LOCAL 提示,PS1以反映路径中的文件夹是使用sshfs.

    首先检查您的终端是否支持颜色提示。~/.kshrc在 yr或中包括以下内容~/.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
    

    接下来,每次使用 wrapper 在本地 FS 上挂载远程卷时sshfs_wrp,都会自动将该挂载的远程卷的路径附加到临时文件,例如/tmp/tmp_rem_vol. 您可以使用 sshfs 命令的简单包装器来执行此操作:

    #!/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 环境变量访问。

    接下来,在您的~/.kshrcor中定义一个函数~/.bashrc来设置一个标志变量 ,remFlag以防[R]字符串"$(pwd)"表明您当前在远程卷子树中工作,该子树以前使用sshfs_wrp. 我用于case便携性。
    编辑: 请注意,一旦在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在 yr 中修改 yr 提示符,~/.kshrc或者~/.bashrc通过在提示符中包含远程卷标志 ,rem_vol以亮绿色,以防使用sshfs_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 连接共存并且远程卷从不同的远程主机安装。

    这对于Debian 或 Arch Lx 平台上的一个bash或shell内的一个 ssh 连接都应该有效。ksh

    在卸载远程卷、会话注销或关闭 ssh 连接时,您还应该注意擦除/tmp/tmp_rem_vol以避免持久性问题。您会发现大量的参考资料和提示也可以实现自动化。

    高温高压

    • 2

相关问题

  • 如何在 Arch Linux 上设置音频,支持多个程序同时发出音频而不创建 asoundrc?

  • 为什么有时需要手动导入密钥?

  • 如何在`zsh`中增加一个动态命名的变量

  • 为什么我不能在 zsh 中定义一个名为 path 的只读变量?

  • 在启动时加载设备

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve