首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按层次结构创建shell子命令

按层次结构创建shell子命令
EN

Stack Overflow用户
提问于 2014-05-15 16:27:08
回答 1查看 1.4K关注 0票数 2

我想为我的剧本建立一个系统-

每个脚本将位于一个文件夹中,该文件夹是命令本身。

脚本本身将充当一个子命令。

例如,名为"git“的目录中有一个名为"who”的脚本,

将允许我在命令行中使用git who运行脚本。

另外,我想创建一个psuedo命令的子命令,意思是当前不可用的命令。例如一些任意的命令子命令。

这有可能吗?

我想以某种方式扩展https://github.com/basecamp/sub以完成任务。

编辑1

代码语言:javascript
复制
#!/usr/bin/env bash

command=`basename $0`
subcommand="$1"
case "$subcommand" in
"" | "-h" | "--help" )
  echo "$command: Some description here" >&2
  ;;
* )
  subcommand_path="$(command -v "$command-$subcommand" || true)"
  if [[ -x "$subcommand_path" ]]; then
    shift
    exec "$subcommand_path" "${@}"
    return $?
  else
    echo "$command: no such command \`$subcommand'" >&2
    exit 1
  fi
  ;;
esac

这是我为新定制命令运行的脚本。

因为它是如此通用,我只是复制粘贴它。

我还是想知道-

它是否足够通用,只识别文件夹名并根据其文件夹名创建脚本?

但是,一个问题是,如果要替换默认命令名(例如git),则它似乎不覆盖默认命令名。

编辑2

在修补了一下之后,这就是我最终要做的事情:

代码语言:javascript
复制
#!/usr/bin/env bash

COMMAND=`basename $0`
SUBCOMMAND="$1"
COMMAND_DIR="$HOME/.zsh/scripts/$COMMAND"

case "$SUBCOMMAND" in
  "" | "-h" | "--help" )
    cat "$COMMAND_DIR/help.txt" 2>/dev/null ||
    command $COMMAND "${@}"
    ;;
  * )
    SUBCOMMAND_path="$(command -v "$COMMAND-$SUBCOMMAND" || true)"
    if [[ -x "$SUBCOMMAND_path" ]]; then
      shift
      exec "$SUBCOMMAND_path" "${@}"
    else
      command $COMMAND "${@}"
    fi
    ;;
esac

这是一个名为“helper”的通用脚本,它指向我拥有的所有脚本目录(例如,ln -s $HOME/bin/helper-sub$HOME/bin/ssh)。

在我的zshrc中,我创建了这个命令来调用所有脚本:

代码语言:javascript
复制
#!/usr/bin/env bash

PATH=${PATH}:$(find $HOME/.zsh/scripts -type d | tr '\n' ':' | sed 's/:$//')
export PATH
typeset -U path

for aliasPath in `find $HOME/.zsh/scripts -type d`; do
  aliasName=`echo $aliasPath | awk -F/ '{print $NF}'`
  alias ${aliasName}=${aliasPath}/${aliasName}
done
unset aliasPath

在这里可以看到示例:https://github.com/iwfmp/zsh/tree/master/scripts

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-05-15 18:52:41

不能将目录作为脚本执行,但可以创建一个包装器来调用目录中的脚本。

您可以使用函数(在概要脚本中或在FPATH中的文件)或使用包装器脚本来实现这一点。

一个简单的函数可能如下所示:

代码语言:javascript
复制
git() {
    local subPath='/path/to/your/git'
    local sub="${1}" ; shift

    if [[ -x "${subPath}/${1}" ]]; then
        "${subPath}/${sub}" "${@}"
        return $?
    else
        printf '%s\n' "git: Unknown sub-command '${sub}'." >&2
        return 1
    fi
}

(这与您链接的sub项目的工作方式相同,只是简化了它。)

当然,如果您确实想为git创建一个子命令(这不仅仅是一个例子),那么您需要确保内置的git命令仍然有效。在这种情况下,你可以这样做:

代码语言:javascript
复制
git() {
    local subPath='/path/to/your/git'
    local sub="${1}"

    if [[ -x "${subPath}/${sub}" ]]; then
        shift
        "${subPath}/${sub}" "${@}"
        return $?
    else
        command git "${@}"
        return 1
    fi
}

但是在这种情况下可能值得指出的是,git支持通过git config添加任意别名。

代码语言:javascript
复制
git config --global alias.who '!/path/to/your/git/who'
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23683860

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档