grep 在 if 语句中始终以 0 退出状态退出

grep 在 if 语句中始终以 0 退出状态退出

我想编写一个模拟 Korn cd 命令的 bash 脚本:用PWDcd old new 替换,然后尝试进入新目录。oldnewcd

这是脚本:

#!/usr/bin/env bash

function korn_cd
{
  case "$#" in
    0 | 1 ) builtin cd $1 ;;
    2     )  if ! echo "$PWD" | grep "$old" ; then
              echo "bash: cd: bad subsitiution";
              return 1;
            fi;

            new_dir=${PWD//$1/$2};
            builtin cd $new_dir; ;;
    *    ) echo "bash: cd: wrong arg count" 1>&2; return 1 ;;
  esac ;
}

在 if 条件下,grep必须检查 if是否old成立。PWD如果不在 中PWD,则必须打印“错误替换”错误消息。我的问题是exit statusofgrep总是0。所以 if 条件永远不会执行。

例如:

PWD="~/Documents/Code"
korn_cd aaaaa bbbbb

我没有看到错误消息“错误替换”。

我该如何修复它?

答案1

您的问题是,old至少在您发布的代码部分中从未设置过。 grep搜索空字符串时将始终匹配"",并返回零退出代码:

$ echo $PWD | grep ""; echo $?
/home/jim
0

答案2

在以下位置使用字符串比较会更有效bash

if [[ $PWD != *$old* ]]; then

假设$old有一定的价值(它没有在你的函数中设置,这是你的问题)。

我认为你的函数的部分实现可能看起来像

cd () {
    if [[ $PWD != *$1* ]]; then
        printf 'cd: string not in pwd: %s\n' "$1"
        return 1
    fi
    builtin cd "${PWD/$1/$2}"
}

(借用内置zsh相同功能的错误消息)cd

该函数不允许用户传递任何其他参数cd。要处理选项,您必须进行完整的命令行解析。

忽略选项:

cd () {
    if [[ $# -lt 2 ]]; then
        builtin cd "$@"
        return
    fi

    if [[ $PWD != *$1* ]]; then
        printf 'cd: string not in pwd: %s\n' "$1"
        return 1
    fi
    builtin cd "${PWD/$1/$2}"
}

相关内容