Bash 布尔开关拒绝按预期操作

Bash 布尔开关拒绝按预期操作,bash,Bash,我有这个代码,我已经工作了几个小时了,我手动执行它,它应该打印出来: 缺少依赖项:nota命令 除非它不能正常工作,我不知道为什么。我做错了什么 __DEPENDENCIES=(touch clear sleep ln pacman sed mkdir wget notacommand) for d in ${__DEPENDENCIES[@]}; do for i in $(echo ${PATH} | tr ":" " "); do if [ -e "${i}/${d}" ] ;

我有这个代码,我已经工作了几个小时了,我手动执行它,它应该打印出来:

缺少依赖项:nota命令

除非它不能正常工作,我不知道为什么。我做错了什么

__DEPENDENCIES=(touch clear sleep ln pacman sed mkdir wget notacommand)
for d in ${__DEPENDENCIES[@]}; do
  for i in $(echo ${PATH} | tr ":" " "); do
    if [ -e "${i}/${d}" ] ; then
      v=true
      break
    else
      v=false
    fi
  done
  if [ v = false ] ; then
    echo "Missing dependency: ${d}"
    exit 1
  fi
done

我很抱歉,因为我知道仅仅发布代码寻求帮助是一种不好的形式,但我实际上一开始就不知道我的代码出了什么问题,所以我甚至不知道该问什么或怎么问。

你忘了一个美元符号;)

如果[v=false]行应为
if[$v=false]


虽然您的脚本只给了我“缺少依赖项:pacman”,但我也应该得到notacommand。

您忘记了一个美元符号;)

如果[v=false]行应为
if[$v=false]


虽然您的脚本只给了我“缺少依赖项:pacman”,但我也应该得到notacommand。

Bash测试不支持布尔值,所以v是一个字符串变量。使用以下命令:

if [ "$v" = "false" ]; then
    echo "Missing dependency: ${d}"
    exit 1
fi

Bash测试不支持布尔值,因此v是一个字符串变量。使用以下命令:

if [ "$v" = "false" ]; then
    echo "Missing dependency: ${d}"
    exit 1
fi

虽然你的问题已经得到了回答,但我有几点建议

您正在循环中执行
$(echo${PATH}|tr:“”)
,这有点低效。实际上,有一种更好的方法来分割你的道路。下面的脚本将路径元素放入数组中。诀窍是临时将bash内部字段分隔符设置为

我还修改了文件存在性检查,以便它使用空字符串表示false,使用find path元素字符串表示true。我使用了现代的
[[
风格的测试,它比旧的
[
风格更方便用户,例如它们对缺少
引号更宽容;FWIW,下面的脚本处理包含空格或引号等令人不快的字符的疯狂文件名。OTOH,
[[
是bash ism,并非所有shell都支持它

#!/bin/bash

__DEPENDENCIES=(touch clear sleep ln pacman sed mkdir zorg wget notacommand)
IFS=':' paths=($PATH)
# for d in "${paths[@]}"; do echo "[$d]"; done

for d in "${__DEPENDENCIES[@]}"
do
    for i in "${paths[@]}"
    do
        v=''
        if [[ -e $i/$d ]]
            then v=$i; break
        fi
    done

    if [[ -z $v ]]
        then echo "Missing dependency: $d"
        else echo "$d is in $i"
    fi
done
这里有一种替代方法,它仅在依赖项实际上是可执行的情况下才查找依赖项

#!/bin/bash

__DEPENDENCIES=(touch clear sleep ln pacman sed mkdir zorg wget notacommand)

for f in "${__DEPENDENCIES[@]}"
do 
    echo -n "$f : "
    which "$f" || echo "NOT found!"
done

虽然你的问题已经得到了回答,但我有几点建议

您正在循环中执行
$(echo${PATH}|tr:“”)
,这有点低效。实际上有一种更好的方法可以分割路径。下面的脚本将路径元素放入数组中。诀窍是临时将bash内部字段分隔符设置为

我还修改了您的文件存在性检查,以便它使用空字符串表示false,使用find path元素字符串表示true。我还使用了现代的
[
样式测试,它比旧的
[
样式更方便用户,例如,它们对缺少的
更宽容。”
quote-marks;FWIW,下面的脚本处理包含空格或引号等令人不快的字符的疯狂文件名。oth,
[[
是一种bash-ism,并非所有shell都支持它

#!/bin/bash

__DEPENDENCIES=(touch clear sleep ln pacman sed mkdir zorg wget notacommand)
IFS=':' paths=($PATH)
# for d in "${paths[@]}"; do echo "[$d]"; done

for d in "${__DEPENDENCIES[@]}"
do
    for i in "${paths[@]}"
    do
        v=''
        if [[ -e $i/$d ]]
            then v=$i; break
        fi
    done

    if [[ -z $v ]]
        then echo "Missing dependency: $d"
        else echo "$d is in $i"
    fi
done
这里有一种替代方法,它仅在依赖项实际上是可执行的情况下才查找依赖项

#!/bin/bash

__DEPENDENCIES=(touch clear sleep ln pacman sed mkdir zorg wget notacommand)

for f in "${__DEPENDENCIES[@]}"
do 
    echo -n "$f : "
    which "$f" || echo "NOT found!"
done

您只是在重新实现
命令-v

__DEPENDENCIES=(touch clear sleep ln pacman sed mkdir wget notacommand)
for d in "${__DEPENDENCIES[@]}"; do
  if ! command -v "$d" > /dev/null; then
    echo "Missing dependency: ${d}"
    exit 1
  fi
done

嗯,也许不是。
命令仍然会找到shell函数、别名等,您可能希望忽略它们。

您只是在重新实现
命令-v

__DEPENDENCIES=(touch clear sleep ln pacman sed mkdir wget notacommand)
for d in "${__DEPENDENCIES[@]}"; do
  if ! command -v "$d" > /dev/null; then
    echo "Missing dependency: ${d}"
    exit 1
  fi
done

嗯,也许不是。
命令
仍会找到shell函数、别名等,您可能想忽略它们。

您一定是在开玩笑……我已经讲了几个小时了……脚本是为Arch Linux系统编写的,我想应该已经指定了。啊,这很有意义。如果您在最后介绍
notacomand2
呢但是,依赖项?它会同时打印它们吗?打印所有缺少的依赖项在我的待办事项列表中,但我尝试先让它工作。明白了,只是确保你知道它
:)
你一定是在开玩笑吧……我已经做了几个小时了……脚本是为Arch Linux系统编写的,我想应该指定。啊,有道理。但是,如果你在依赖项末尾引入
notacomand2
,会怎么样?它会同时打印它们吗?打印所有缺少的依赖项在我的待办事项列表中,但我尝试先让它工作。明白了,只要确保你知道它
:)
喜欢发布的代码并自动指出这个问题.哦,哇,太酷了。我以前从未听说过那个网站,我肯定会开始使用它…喜欢发布代码并自动指出这个问题。哦,哇,太酷了。我以前从未听说过那个网站,我肯定会开始使用它…是的。如果你在scr中使用裸
true
false
,可能会发生有趣的事情ipt,因为它们是命令名。是的。如果在脚本中使用裸
true
false
,可能会发生有趣的事情,因为它们是命令名。足够正确。根据问题中的代码,我假设FatalKeystroke只想检查可执行文件,这就是为什么我的备用版本使用
which
。当然,t他的可能只是一个编程练习…没错。我从问题中的代码中假设FatalKeystroke只是想检查可执行文件,这就是为什么我的替代版本使用
,它
。当然,这可能只是一个编程练习。。。