Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在bashshell中编写漂亮优雅的linux命令_Linux_Bash_Shell - Fatal编程技术网

如何在bashshell中编写漂亮优雅的linux命令

如何在bashshell中编写漂亮优雅的linux命令,linux,bash,shell,Linux,Bash,Shell,我在Ubuntu 12.04上的虚拟机上运行了几个web应用程序 我发现自己在ssh到VM中时经常输入以下内容 cd/var/virtual/app1.com/ cd/var/virtual/app2.com/ cd/var/virtual/app3.com/ 每行代表一个单独的webapp根目录,供我执行某些指令 这是一个懒惰的程序员,他问我是否有办法打字 go_app1 go_app2 go_app3 我知道如何使用bash脚本执行上述操作 但我最终会打字 ./GoApp.sh -a

我在Ubuntu 12.04上的虚拟机上运行了几个web应用程序

我发现自己在ssh到VM中时经常输入以下内容

  • cd/var/virtual/app1.com/
  • cd/var/virtual/app2.com/
  • cd/var/virtual/app3.com/
每行代表一个单独的webapp根目录,供我执行某些指令

这是一个懒惰的程序员,他问我是否有办法打字

  • go_app1
  • go_app2
  • go_app3
我知道如何使用bash脚本执行上述操作

但我最终会打字

./GoApp.sh -app app1
我想通过简单地键入go_app1使其更加优雅

建议

编辑:

我使用了最高评级的答案,我在Ubuntu中得到了这个错误消息

我哪里出错了

EDIT2:


我已在此处将错误改写为另一个问题。

您可以通过在.bash\u配置文件中放置以下内容来使用别名

alias go_app1='cd /var/virtual/app1.com/'

这样做之后,键入go_app1应该会更改您的目录。

为每个目录定义一个别名肯定会起作用。但是,由于您有多个期望的快捷方式跟随一个模式,请考虑一个函数。

function go_app() { cd /var/virtual/app$1.com/; }
用法:

go_app 1

将函数定义放在~/.bashrc中。

搜索bash命令历史记录是否足够好?我还经常需要登录到长目录结构,但我通常通过Ctrl-R进行登录。例如,如果我最近在你的app1.com上安装了cd,我会按 Ctrl-R 然后键入app1.com,将显示使用app1.com的最后一个命令,此时按enter键即可完成。如果不是“cd”,请再按Ctrl-R几次,直到它出现

更详细一点:


当然,只有当您关心键入的数量,而不是试图以编程方式执行此操作时,并且只有当“cd”命令在显式包含“app1.com”(或任何其他简短区分模式)的命令列表中是相当新的命令时,这才有效。

我将设置
$CDPATH
变量(在
bash
)要搜索的所有目录,包括当前目录(首先),如:


鉴于此,目录名很短,我可以键入(而不是在历史记录中搜索)

改进corkin别名建议,但鉴于“命名”的灵活性(参数为app1.com、app2.com等),此解决方案使用单个别名解决此问题:

alias go_app='cd /var/virtual/; cd '
后来,

go_app app1.com
cd
放入/var/virtual/app1.com/。关于命名:我将它命名为
cd\u app

另一方面,没有参数的go_应用程序将把你踢回你的家(因为最后一个命令是没有参数的cd)。

将此添加到你的
。bashrc

_make_go_apps() {
    local r=/var/virtual
    local d qd
    while read d; do
        printf -v qd '%q' "$r/$d"
        eval "go_${d%.com}() { cd -- $qd; }"
    done < <( find "$r" -maxdepth 1 -regex ".*/app[0-9]+\.com" -type d -printf '%f\n')
}
clean_go_apps() {
    local r=/var/virtual
    local f
    while read _ _ f; do
        [[ $f =~ ^go_app[[:digit:]]+$ ]] || continue
        [[ -d $r/${f#go_}.com ]] && continue
        unset -f $f
    done < <(declare -F)
}
readonly _go_apps_basedir=/var/virtual
make_go_apps() {
    local d qd
    while IFS= read -d '' d; do
        printf -v qd '%q' "$_go_apps_basedir/$d"
        eval "go_${d%.com}() { cd -- $qd; }"
    done < <( find "$_go_apps_basedir" -maxdepth 1 -regex ".*/app[0-9]+\.com" -type d -printf '%f\0')
}

clean_go_apps() {
    local f
    while read _ _ f; do
        [[ $f =~ ^go_app[[:digit:]]+$ ]] || continue
        [[ -d "$_go_apps_basedir/${f#go_}.com" ]] && continue
        unset -f $f
    done < <(declare -F)
}

make_go_apps
readonly _go_apps_basedir=/var/virtual
make_go_functions() {
    local f d qd saved_shopt
    saved_shopt=$(shopt -p)
    shopt -s extglob nullglob
    for d in "$_go_apps_basedir"/+([[:alpha:][:digit:]\-\._]).com/; do
        f=${d#$_go_apps_basedir/}
        printf -v qd '%q' "$d"
        eval "go_${f%.com/}() { cd -- $qd; }"
    done
    eval "$saved_shopt"
}

clean_go_apps() {
    local f
    while read _ _ f; do
        [[ $f =~ ^go_.+$ ]] || continue
        [[ -d "$_go_apps_basedir/${f#go_}.com" ]] && continue
        unset -f $f
    done < <(declare -F)
}

make_go_functions
完成了

如果创建了新目录,则只需重新启动功能
\u make\u go\u apps

这种方法满足OP的所有要求,并且足够通用,能够处理任意数量的目录

eval
是一种邪恶的方法,但使用起来是安全的(使用经过净化的变量读取,尽管在这里它是无用的;但是如果有一天你想推广这个方法,你至少会纠正这一部分)

除非您完全知道自己在做什么:注意包含空格、换行符、尾随换行符等的文件名,否则不要尝试推广此方法。

备注。

  • 如果要更改位置
    /var/virtual
    ,只需更改局部变量
    r
    ,确保它是绝对路径
  • Tab完成课程效果非常好(Tab Tab将向您展示各种可能性)
  • 如果删除某些目录,您可能希望
    \u clean\u go\u apps
    只保留相关的
    go\u appX
    。一种可能性是(它将进入您的
    .bashrc
    ):

    我标记了变量
    \u go\u apps\u basedir
    readonly
    ,这样就不会无意中更改它。这次我选择在read中使用
    IFS='
    -d'
    ,在
    find
    命令中使用
    -printf'%f\0'
    ,向您展示如何在解析
    find
    的输出时执行安全操作


    我仍然担心
    \u make\u go\u apps
    函数中的
    find
    ,因为它不是100%纯bash解决方案。下面是一个100%纯bash解决方案:

    readonly _go_apps_basedir=/var/virtual
    make_go_apps() {
        local f d qd saved_shopt
        saved_shopt=$(shopt -p)
        shopt -s extglob nullglob
        for d in "$_go_apps_basedir"/app+([[:digit:]]).com/; do
            f=${d#$_go_apps_basedir/}
            printf -v qd '%q' "$d"
            eval "go_${f%.com/}() { cd -- $qd; }"
        done
        eval "$saved_shopt"
    }
    
    clean_go_apps() {
        local f
        while read _ _ f; do
            [[ $f =~ ^go_app[[:digit:]]+$ ]] || continue
            [[ -d "$_go_apps_basedir/${f#go_}.com" ]] && continue
            unset -f $f
        done < <(declare -F)
    }
    
    make_go_apps
    

    您可以直接使用
    /GoApp.sh app1
    ,跳过选项名称……我的建议是:如果您想要优雅,请为bash脚本选择更优雅的名称,并将它们放在$PATH中的目录中。这样做,你就可以输入
    go-app1
    ,这在我的书中肯定算是优雅的。排名靠前的答案并不总是最好的。请考虑我的回答,它满足你的100%的要求!我喜欢这种方法,但是如果只让函数
    go_app(){cd/var/virtual/app${1}.com/}
    然后按照您的指示使用它,会不会更容易一些。。。(我想OP是说,
    GoApp
    是一个shell脚本,负责
    cd
    ing…)是的。看来GoApp.sh只是解决实际问题的一种可能的方法。谢谢。你好,我在用ubuntu。我一直收到这个错误消息。对于linux用户,它是~/.bashrc文件。然后,如果你有1000个应用程序目录,这不是一个好的解决方案。在这种情况下,我更喜欢这个:;)@Idrissneumann我尝试了你的建议,但不断收到此命令未找到消息。我理解你为什么不想删除你前面的部分,但是你能为你建议的答案写一个简明的摘要吗?现在,我不能确定我应该采纳你答案的哪一部分。@KimSia最下面的部分很好:把它放在
    .bashrc
    的底部,当你打开一个新的终端时
    readonly _go_apps_basedir=/var/virtual
    make_go_apps() {
        local d qd
        while IFS= read -d '' d; do
            printf -v qd '%q' "$_go_apps_basedir/$d"
            eval "go_${d%.com}() { cd -- $qd; }"
        done < <( find "$_go_apps_basedir" -maxdepth 1 -regex ".*/app[0-9]+\.com" -type d -printf '%f\0')
    }
    
    clean_go_apps() {
        local f
        while read _ _ f; do
            [[ $f =~ ^go_app[[:digit:]]+$ ]] || continue
            [[ -d "$_go_apps_basedir/${f#go_}.com" ]] && continue
            unset -f $f
        done < <(declare -F)
    }
    
    make_go_apps
    
    readonly _go_apps_basedir=/var/virtual
    make_go_apps() {
        local f d qd saved_shopt
        saved_shopt=$(shopt -p)
        shopt -s extglob nullglob
        for d in "$_go_apps_basedir"/app+([[:digit:]]).com/; do
            f=${d#$_go_apps_basedir/}
            printf -v qd '%q' "$d"
            eval "go_${f%.com/}() { cd -- $qd; }"
        done
        eval "$saved_shopt"
    }
    
    clean_go_apps() {
        local f
        while read _ _ f; do
            [[ $f =~ ^go_app[[:digit:]]+$ ]] || continue
            [[ -d "$_go_apps_basedir/${f#go_}.com" ]] && continue
            unset -f $f
        done < <(declare -F)
    }
    
    make_go_apps
    
    readonly _go_apps_basedir=/var/virtual
    make_go_functions() {
        local f d qd saved_shopt
        saved_shopt=$(shopt -p)
        shopt -s extglob nullglob
        for d in "$_go_apps_basedir"/+([[:alpha:][:digit:]\-\._]).com/; do
            f=${d#$_go_apps_basedir/}
            printf -v qd '%q' "$d"
            eval "go_${f%.com/}() { cd -- $qd; }"
        done
        eval "$saved_shopt"
    }
    
    clean_go_apps() {
        local f
        while read _ _ f; do
            [[ $f =~ ^go_.+$ ]] || continue
            [[ -d "$_go_apps_basedir/${f#go_}.com" ]] && continue
            unset -f $f
        done < <(declare -F)
    }
    
    make_go_functions