linux If语句不能通过bash脚本工作,但可以在bash上工作,为什么?

inn6fuwd  于 5个月前  发布在  Linux
关注(0)|答案(1)|浏览(65)

有没有人能帮帮我

for f in $(grep -Ev '^(#|$)' $(readlink -f $(git config --get core.excludesfile)) | awk '{$1=$1};1' | tr -d '\r' ); do for g in $(git ls-files --others --ignored --exclude-standard); do if [ $f == $g ]; then echo "ok $f $g"; fi; ls $f; done; done

字符串
我正在测试上面的脚本,当我直接在bash上运行它时,它可以像预期的那样工作,但是当我通过脚本执行它时,它不工作。主要是if语句没有执行,有人能告诉我为什么或者有什么替代方案吗?
我尝试了不同的东西,比如带shopt,主要操作if语句,每次在运行时它都能工作,但在脚本中它不能!
下面是从一行代码转换而来的代码:

for f in $(grep -Ev '^(#|$)' $(readlink -f $(git config --get core.excludesfile)) | awk '{$1=$1};1' | tr -d '\r' ); do 
    for g in $(git ls-files --others --ignored --exclude-standard); do
        if [ $f == $g ]; then 
            echo "ok $f $g"
        fi 
        ls $f
    done
done

dkqlctbz

dkqlctbz1#

您的for ... in循环是一个反模式,请使用while IFS= read -r循环,请参阅https://mywiki.wooledge.org/BashFAQ/001http://shellcheck.net可以帮助您解决各种其他问题,因为您的脚本当前会根据环境设置、运行它的目录内容、运行它的文件名等执行各种不同的操作。
从你的代码中我可以看出,这(使用bash 4.3或更高版本来测试-v的数组索引存在性)似乎是你想要做的,但这是一个未经测试的猜测,因为你没有提供示例输入和预期输出:

#!/usr/bin/env bash

declare -A gitLsFiles
while IFS= read -r file; do
    gitLsFiles["$file"]=1
done < <(
    git ls-files --others --ignored --exclude-standard
)

while IFS= read -r file; do
    if [[ -v gitLsFiles["$file"] ]]; then
        echo "ok $file"
    fi
    ls "$file"
done < <(
    git config --get core.excludesfile |
        awk '{sub(/\r$/,"")} !/^(#|$)/ { $1=$1; print }'
)

字符串
这个awk命令将把git config输出中的所有白色空格转换为单个空白字符,就像您当前的脚本所做的那样,我不知道您是否真的想这样做。
在上面的代码中,我假设你并不真的想在git config的每一行输出中调用git ls-files一次,也不真的想在同一个文件名下echo两次,并在同一个git config输出行中多次执行ls。我还假设你只是想从行的末尾删除\r s,而不是在所有地方,如果你的输入可以包含行结尾\r s,那么你需要在测试^$之前删除它们,而不是在测试之后,所以我移到了发生这种情况的地方。

相关问题