【问题标题】:No such file or directory in find running .sh在 find running .sh 中没有这样的文件或目录
【发布时间】:2017-11-09 14:10:28
【问题描述】:

在 osx 上运行...

    cd ${BUILD_DIR}/mydir && for DIR in $(find ./  '.*[^_].py' |  sed  's/\/\//\//g' | awk -F "/" '{print $2}' | sort |uniq | grep -v .py); do
            if [ -f $i/requirements.txt ]; then
               pip install -r $i/requirements.txt -t $i/
            fi

            cd ${DIR} && zip -r ${DIR}.zip *  > /dev/null && mv ${DIR}.zip ../../ && cd ../
        done

    cd ../

错误:

(env) ➜ sh package_lambdas.sh find: .*[^_].py: No such file or directory

为什么?

【问题讨论】:

  • 为什么这个问题有makefile标签?

标签: python macos shell makefile terminal


【解决方案1】:

find 将要搜索的目录列表作为参数。您提供了看似正则表达式的内容。因为没有名为(字面意思).*[^_].py 的目录,所以 find 返回错误。

下面我已经修改了你的脚本以纠正这个错误(如果我理解你的意图)。因为这些天我看到了很多写得不好的 shell 脚本,所以我冒昧地把它“传统化”了。请看看你是否也觉得它更具可读性。

变化:

  • 使用#!/bin/sh,保证在类Unix系统上。比 bash 更快,除非(如 OS X)它是 bash。
  • 使用小写的变量名来区分系统变量(而不是隐藏它们)。
  • 避开变量的大括号 (${var});在简单的情况下不需要它们
  • 不要通过管道输出到/usr/bin/true;把它路由到dev/null,如果这就是你的意思
  • rm -f 根据定义不能失败;如果你的意思是|| true,那是多余的
  • thendo 放在不同的行上,更易于阅读,这就是 Bourne shell 语言的用途
  • &&|| 充当续行,这样您就可以一步一步看到发生了什么

我建议的其他更改:

  • 临时更改工作目录时使用子shell。当它终止时,工作目录会自动恢复(由父级保留),为您节省cd .. 步骤和错误。

  • 使用set -e 使脚本在出错时终止。对于预期的错误,请明确使用|| true

  • grep .py 更改为grep '\.py$',只是为了更好地衡量。

  • 为避免倾斜火柴棍综合症,请使用 / 以外的其他内容作为 sed 替代分隔符,例如 sed 's://:/:g'。但是使用 awk -F '/+' '{print $2}' 可以完全避免 sed

修订版:

#! /bin/sh

src_dir=lambdas
build_dir=bin

mkdir -p $build_dir/lambdas
rm -rf $build_dir/*.zip
cp -r $src_dir/* $build_dir/lambdas

#
# The sed is a bit complicated to be osx / linux cross compatible :
#   ( .//run.sh vs ./run.sh
#
cd $build_dir/lambdas &&
    for L in $(find .  -exec grep -l '.*[^_].py' {} + |
                    sed  's/\/\//\//g' |
                    awk -F "/" '{print $2}' |
                    sort |
                    uniq |
                    grep -v .py)
    do
        if [ -f $i/requirements.txt ]
        then
            echo "Installing requirements"
            pip install -r $i/requirements.txt -t $i/
        fi
        cd $L &&
        zip -r $L.zip *  > /dev/null &&
        mv $L.zip ../../ &&
        cd ../
    done
cd ../

【讨论】:

  • "rm -f by definition cannot fail"——在这种使用中它可能永远不会失败,但“rm -f”通常肯定会失败。例如,试试rm -f /
【解决方案2】:

find(1) 联机帮助页说它的参数是[path ...] [expression],其中“表达式”由“主要”和“操作数”(-标志)组成。 '.*[^-].py' 看起来不像任何表达式,因此它被解释为路径,并报告工作目录中没有名为 '.*[^-].py' 的文件。

也许你的意思是:

find ./ -regex '.*[^-].py'

【讨论】:

    猜你喜欢
    • 2018-06-18
    • 2019-09-06
    • 2019-12-10
    • 2019-03-04
    • 2023-04-09
    • 1970-01-01
    • 2019-03-17
    • 2018-01-15
    • 2017-04-12
    相关资源
    最近更新 更多