【问题标题】:/bin/ls: Argument list too long/bin/ls: 参数列表太长
【发布时间】:2020-05-26 09:06:43
【问题描述】:

尝试在运行最新 macOS 的最大 MBP 16" 上使用 bash 脚本将超过 10K 推文的 twitter 帐户转换为另一种格式。

运行几分钟后输出多个句点,它显示line 43: /bin/ls: Argument list too long。假设这个问题与推文的数量有关,所以虽然我可以尝试分成小块作为最后的手段,但不知道避免错误的最大数量是多少,所以决定首先寻找解决方案。

搜索了 Google 和 SO,发现“bash: /bin/ls: Argument list too long”。如果我的问题是相同的,听起来用“find -name”替换“ls”可能会有所帮助。尝试过同样的错误,但可能不是正确的语法。

目前使用“ls”的两行如下(第一行是当前报错的那一行):

for fileName in `ls ${thisDir}/dotwPosts/p*` ; do

printf "`ls ${thisDir}/dotwPosts/p* | wc -l` posts left to import.\n"

尝试将第一行更改为(错误为 /usr/bin/find: Argument list too long)。

for fileName in `find -name ${thisDir}/dotwPosts/p*` ; do

可能需要提供额外的代码,但不想让问题过于具体地满足我的需求,希望其他人看到这个常见错误,而其他 stackoverflow 答案似乎并不适用。

【问题讨论】:

  • 为什么需要使用ls?就for fileName in ${thisDir}/dotwPosts/p*
  • Barmar 说的很对;但作为记录,如果您确实想使用find 解决此问题,正确的版本是find "$thisDir/dotwPosts" -maxdepth 1 -name 'p*'仅仅ls 替换为find -name 是不可能的,因为您将发送给find 的所有参数与发送给ls 的参数相同。如果内核不允许后者,那么它也不会允许前者。
  • find 在迭代其输出方面也不比ls 好。
  • @cchiera :另一种缩短参数列表的方法是使用cd ${thisDir}/dotwPosts; for fileName in *;...; do。当然,您只有fileName 中文件的基本名称,并且您的工作目录也不同,但两者都是微不足道的问题。如果您仍然有太多目录条目,请考虑将循环替换为find .... | xargs ....,如果您的逻辑允许的话。由于我不知道循环内部发生了什么,所以我不知道这种替代方案的可行性。

标签: bash macos


【解决方案1】:

试试这个:

for file in "${thisDir}/dotwPosts/p"*
do
    # exclude non plain files
    [[ -f $file ]] || continue 
    # do something with "$file"
    ...
done

我引用了 "${thisDir}/dotwPosts/p",所以 var thisDir 不能包含相关的通配符,但可以使用空格。否则删除引号。

【讨论】:

    【解决方案2】:

    要在 bash 中遍历目录中的文件,请将文件名打印为零分隔流并读取它。这样您就不需要在任何地方一次存储所有文件名:

    find "${thisDir}/dotwPosts/" -maxdepth 1 -type f -name 'p*' -print0 |
    while IFS= read -d '' -r file; do
       printf "%s\n" "$file"
    done
    

    要获得计数,为每个文件输出一个字符并计算字符数:

    find "${thisDir}/dotwPosts/" -maxdepth 1 -type f -name 'p*' -printf . | wc -c
    

    不要使用 ` 反引号,不鼓励他们使用。 Bash hackers wiki discouraged and deprecated syntax。请改用$(...)

    for fileName in $(...) 是 bash 中常见的反模式。如果您想迭代另一个命令的输出,很可能您应该使用while IFS= read -r line 循环。 bashfaq How can I read a file (data stream, variable) line-by-line (and/or field-by-field)?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-07
      • 1970-01-01
      • 1970-01-01
      • 2014-08-30
      • 2015-04-27
      • 2019-02-22
      • 2021-03-28
      • 2018-07-24
      相关资源
      最近更新 更多