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
    • 最新
    • 标签
主页 / ubuntu / 问题 / 1245784
Accepted
Student of Science
Student of Science
Asked: 2020-06-02 05:49:26 +0800 CST2020-06-02 05:49:26 +0800 CST 2020-06-02 05:49:26 +0800 CST

自定义 bash shell

  • 772

我想以一种非常具体的方式自定义我的 bash shell,具体到我不知道是否可行。目前,我的外壳是这样的:

myname@ubuntu /home/myname:
>>

其中 myname 是我的用户名。我在以下行中自定义了外壳~/.bashrc:

PS1='${debian_chroot:+($debian_chroot)}\u@\h `pwd`:\n>> '

当我按 Enter 键时,会发生以下情况:

myname@ubuntu /home/myname:
>>
myname@ubuntu /home/myname:
>>

取而代之的是,我希望发生以下情况:

myname@ubuntu /home/myname:
>>
>>

此外,如果我输入一个命令,会发生什么应该是这样的:

myname@ubuntu /home/myname:
>> echo hello
hello
myname@ubuntu /home/myname:
>>

以下情况不应发生

myname@ubuntu /home/myname:
>>echo hello
hello
>>

这可能吗?如果是这样,该怎么做?

更新

多亏了 ChrisAga 的回应,我才得以实现我的目标。

这是脚本

# don't put duplicate lines or lines starting with space in the history.
HISTCONTROL=ignoreboth

customprompt() {
    # the current number of lines in bash history:
    bash_history_size=$(fc -l -1)
    bash_history_size=${bash_history_size%%[^0-9]*}

    # set an initial value to the number of lines
    # in bash history stored from the last time
    # this function was executed. This avoids bugs
    # when running the first command in the current
    # shell session
    if [ -n "$bash_history_lastsize" ]; then
        bash_history_lastsize=0
    fi

    # if the current number of lines in bash history
    # is different from the last number of lines, then
    # we print the user name and the current directory.
    # otherwise, we just print >>
    if [ "${bash_history_size}" != "${bash_history_lastsize}" ]; then
        PS1='\[\033[01;32m\]\u@\h \[\033[00m\]`pwd`:\n>> '
    else
        PS1=">> "
    fi

    # update the last value to the current value
    bash_history_lastsize=${bash_history_size}
}

PROMPT_COMMAND=customprompt
command-line bash
  • 2 2 个回答
  • 351 Views

2 个回答

  • Voted
  1. Best Answer
    ChrisAga
    2020-06-09T10:07:24+08:002020-06-09T10:07:24+08:00

    实际上,普通的 bash 有一个解决方案!

    唯一的限制是与 bash 命令历史记录中的重复预防不兼容。因此,如果您不介意 bash 历史记录中有重复项,则可以在 bash 中设置以下内容~/.bashrc:

    HISTCONTROL=ignorespace
    
    function pprompt {
       local hcount=$(fc -l -1)
       echo ${hcount}
       hcount=${hcount%%[^0-9]*}
       if [ "${hcount}" != "${ocount}" ]; then 
          PS1="\[\e]0;\u@\h: \w\a\]\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w:\[\033[00m\]\n>>"
       else 
          PS1=">>"
       fi
       ocount=${hcount}
    }
    
    PROMPT_COMMAND=pprompt
    

    默认情况下HISTCONTROL=ignoreboth,这相当于ignorespace:ignoredups所以你必须改变它。

    该pprompt函数获取历史记录中的最后一条命令,并将其编号与先前存储的值进行比较。如果你只是按回车,数字不会改变,所以如果这个数字已经改变,我们将 PS1 设置为完整提示,否则,我们将其设置为>>.

    最后PROMPT_COMMAND=pprompt,在回显主提示 ( ) 之前,需要 bash 来执行 pprompt $PS1。

    NB1。如果您不喜欢将主路径显示为~,可以将 \w 替换为 `pwd`。

    NB2。如果我们可以获得实际的 bash 命令号(我们可以!#在提示符中显示的那个)而不是历史命令号,我们将获得与历史重复数据删除兼容的解决方案。

    • 3
  2. Parsa Mousavi
    2020-06-02T13:33:40+08:002020-06-02T13:33:40+08:00

    据我所知,你不能简单地使用普通的 bash 来做到这一点。但相反,您必须几乎从头开始实现自己的 shell(不要害怕,我已经完成了,它只需要不到 30 行代码)。

    这是代码(custom_shell.sh):

    RED='\033[0;31m'                         #Definition of some ASCII colors
    WHITE='\033[1;37m'                       #Replace them with whatever color you want
    
    TMP_COMM_BUF="/tmp/custom_shell_buf"     #For temporary storage of commands
    
    if [ "$1" == "e" ]
    then 
        printf "${RED}>> ${WHITE}"           #When you just pressed enter
    else
        printf  "${RED}$PWD >> ${WHITE} "    #After the execution of some command
    fi
    
    
    exec 3<&1                                #Custom file descriptor
    read -u 3 comm_buf                       #Read commands from stdin
    echo $comm_buf  > $TMP_COMM_BUF          #Store commands (exec cannot execute multiple commands at once , so we need it)
    chmod +x $TMP_COMM_BUF                   #Make it executable
    if ! [ -z "$comm_buf" ] 
    then
        echo custom_shell.sh >> $TMP_COMM_BUF      #Recover the prompt after the execution ( It's assumed that the name of the file is custom_shell.sh and it's available in the $PATH )
        exec $TMP_COMM_BUF                         #Execute !!!
    else
        exec custom_shell.sh e                     #If nothing specified , then just show ">>"
    fi
    
    

    限制:

    由于它不能使用 bash 中存在的行编辑功能,因此不能Ctrl+C用于中断或Ctrl+L清除终端。并且没有命令完成和 shell 历史记录。

    安全考虑:

    /tmp/custom_shell_buf由于它在执行命令之前使用未加密的文件(

    所以毕竟作为一个爱好工作就足够了,它也满足了你的需求。如果你愿意,你可以添加更多的功能。

    如果有人有更好的建议,我很高兴听到。

    快乐的黑客;)

    • 1

相关问题

  • 如何从命令行仅安装安全更新?关于如何管理更新的一些提示

  • 如何从命令行刻录双层 dvd iso

  • 如何从命令行判断机器是否需要重新启动?

  • 文件权限如何工作?文件权限用户和组

  • 如何在 Vim 中启用全彩支持?

Sidebar

Stats

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

    如何运行 .sh 脚本?

    • 16 个回答
  • Marko Smith

    如何安装 .tar.gz(或 .tar.bz2)文件?

    • 14 个回答
  • Marko Smith

    如何列出所有已安装的软件包

    • 24 个回答
  • Marko Smith

    无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗?

    • 25 个回答
  • Martin Hope
    Flimm 如何在没有 sudo 的情况下使用 docker? 2014-06-07 00:17:43 +0800 CST
  • Martin Hope
    Ivan 如何列出所有已安装的软件包 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    La Ode Adam Saputra 无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗? 2010-11-30 18:12:48 +0800 CST
  • Martin Hope
    David Barry 如何从命令行确定目录(文件夹)的总大小? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher “以下软件包已被保留:”为什么以及如何解决? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford 如何删除 PPA? 2010-07-30 01:09:42 +0800 CST

热门标签

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

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

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve