2

我有一个返回系统路径的简短 shell 程序。我想要做的是使用 bash 别名 CD 到该路径。

我的理想输出是

~$ pwd
    /home/username
~$ mark home
~$ cd /
/$ pwd
    /
/$ place home
~$ pwd
    /home/username

我有“标记”部分工作,但“地方”不是:

alias place="cd \"~/marker.sh go $@\";"

我的想法是我想 cd 到输出~/marker.sh go $@

问题是 bash 将其解释为一个命令,并给出错误:

-bash: cd: ~/marker.sh go : No such file or directory
-bash: home: command not found

我假设这意味着 shell 将整个别名解析为字符串。

我为别名 $()、`` 等的 shell 脚本部分尝试了各种形式的引用,但它们要么尝试在 bash 启动时运行脚本,要么根本不执行,只保留一个字符串。

我编写这个主要是为了学习 bash 命令,但我无法弄清楚这一部分!

我在 iTerm 1.0.0.20130624 中运行 OSX 10.9,如果这很重要的话。

编辑:我知道脚本中的 cd-ing 不起作用,这就是为什么我试图使用我的程序返回正确的路径并使用内置的别名系统来进行目录的实际更改。

4

2 回答 2

2

你想要一个函数,而不是别名:

place () {
    cd $( ~/marker.sh go "$@" )
}

别名不带参数;它们只是就地扩展,参数发生在别名扩展为之后。

(你应该总是更喜欢一个函数而不是一个别名,除非这个函数不能适应你想要的。)

于 2013-10-28T18:15:14.307 回答
2

使用函数,而不是别名或外部 bash 脚本!

在您.bashrc或由它获取的任何文件中,或您将手动获取的任何文件中,放置这个完全可用的脚本!

declare -A _mark_dir_hash

mark() {
   [[ -z $1 ]] && { listmarks; return 0; }
   if [[ -n ${_mark_dir_hash[$1]} ]] && [[ $1 != ${_mark_dir_hash[$1]} ]]; then
       echo "Mark $1 was already set to ${_mark_dir_hash[$1]}... replaced with new mark"
   fi
   _mark_dir_hash[$1]=$(pwd)
}

place() {
   [[ -z $1 ]] && { echo >&2 "You must give a mark name to go to!"; return 1; }
   [[ -z ${_mark_dir_hash[$1]} ]] && { echo >&2 "Mark $1 unknown!"; return 1; }
   cd "${_mark_dir_hash[$1]}"
}

listmarks() {
   [[ -z ${!_mark_dir_hash[@]} ]] && { echo "No marks!"; return 0; }
   for i in "${!_mark_dir_hash[@]}"; do
      printf '%s --> %s\n' "$i" "${!_mark_dir_hash[@]}"
   done
}

removemark() {
   [[ -z $1 ]] && { echo >&2 "You must give a mark name to remove!"; return 1; }
   unset _mark_dir_hash[$1]
}

clearmarks() {
   _mark_dir_hash=()
}

哈,我刚刚意识到您使用的是 Mac,因此您可能会被不支持关联数组的老式 bash 版本卡住。对你太坏了。然而,这可能对使用现代 shell 的其他人有用!

于 2013-10-28T18:41:34.360 回答