bash csh/sh for 循环 - 如何?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5993310/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 20:30:26  来源:igfitidea点击:

csh/sh for loop - how to?

bashshellshcsh

提问by Paul J

i'm trying to write a for loop that executes 2 scripts on FreeBSD. I don't care if it's written in sh or csh. I want something like:

我正在尝试编写一个在 FreeBSD 上执行 2 个脚本的 for 循环。我不在乎它是用 sh 还是 csh 编写的。我想要这样的东西:

for($i=11; $i<=24; $i++)
{
   exec(tar xzf 'myfile-1.0.' . $i);
   // detect an error was returned by the script
   if ('./patch.sh')
   {
      echo "Patching to $i failed\n";
   }
}

Does anyone know how to do this please?

请问有人知道怎么做吗?

Thanks

谢谢

采纳答案by cdarke

csh does loops fine, the problem is that you are using exec, which replaces the current program (which is the shell) with a different one, in the same process. Since others have supplied sh versions, here is a csh one:

csh 确实循环良好,问题是您正在使用 exec,它在同一进程中用不同的程序替换当前程序(即外壳程序)。由于其他人提供了 sh 版本,这里是一个 csh 版本:

    #!/bin/csh
    set i = 11
    while ($i < 25)
        tar xzf "myfile-1.0.$i"

        # detect an error was returned by the script   
        if ({./patch.sh}) then     
            echo "Patching to $i failed"   
        endif
        @ i = $i + 1
    end

Not sure about the ./patch.share you testing for its existence or running it? I am running it here, and testing the result - true means it returned zero. Alternatively:

不确定./patch.sh您是在测试它的存在还是在运行它?我在这里运行它,并测试结果 - true 意味着它返回零。或者:

        # detect an error was returned by the script   
        if (!{tar xzf "myfile-1.0.$i"}) then     
            echo "Patching to $i failed"   
        endif

回答by William Pursell

The typical way to do this in sh is:

在 sh 中执行此操作的典型方法是:

for i in $(seq 11 24); do 
   tar xzf "myfile-1.0$i" || exit 1
done

Note that seqis not standard. Depending on the availability of tools, you might try:

请注意,这seq不是标准的。根据工具的可用性,您可以尝试:

jot 14 11 24

or

或者

perl -E 'say for(11..24)'

or

或者

yes '' | nl -ba | sed -n -e 11,24p -e 24q

I've made a few changes: I abort if the tar fails and do not emit an error message, since tar should emit the error message instead of the script.

我做了一些更改:如果 tar 失败,我会中止并且不发出错误消息,因为 tar 应该发出错误消息而不是脚本。

回答by David W.

Wow! No BASH. And probably no Kornshell:

哇!没有 BASH。可能没有 Kornshell:

i=11
while [ $i -le 24 ]
do
    tar xzf myfile-1.0.$i
    i=`expr $i + 1`
    if ./patch.sh
    then
        echo "patching to $i failed"
    fi
done

Written in pure Bourne shell just like God intended.

就像上帝的本意一样,用纯 Bourne shell 编写。

Note you have to use the exprcommand to add 1 to $i. Bourne shell doesn't do math. The backticks mean to execute the command and put the STDOUT from the command into $i.

请注意,您必须使用该expr命令将 1 添加到$i. Bourne shell 不会做数学运算。反引号表示执行命令并将命令中的 STDOUT 放入$i.

Kornshell and BASH make this much easier since they can do math and do more complex for loops.

Kornshell 和 BASH 使这变得更容易,因为它们可以进行数学运算并进行更复杂的 for 循环。

回答by gnudna

Well what i just did is the following.

那么我刚刚做的是以下。

sh

Load sh shell and then for loop works like on linux.

加载 sh shell 然后 for 循环就像在 linux 上一样工作。

for i in 1 2 3 4 5 6 7 8 9; do dd if=/dev/zero of=/tmp/yourfilename$i.test bs=52428800 count=15; done

回答by Axel

I think you should just use bash. I don't have it here, so it cannot test it, but something along this should work:

我认为你应该只使用 bash。我这里没有它,因此无法对其进行测试,但是应该可以:

for ((I=11; I<=24; I++)) ; do
   tar xzf myfile-1.0.$I || echo Patching to $I failed
done

EDIT: Just read the comments and found out there's no bash in FreeBSD default installation. So this might not work at all - I'm not sure about the differences between (t)csh and bash.

编辑:只要阅读评论,就会发现 FreeBSD 默认安装中没有 bash。所以这可能根本不起作用 - 我不确定 (t)csh 和 bash 之间的区别。