为什么此 shell 脚本中的 for 循环在执行第二次迭代之前执行第一次迭代两次?

问题描述 投票:0回答:1

我有一个 bash 脚本:

#! usr/bin/env bash
# test bash script to call python scripts

cd ~/python
for ((i = 1; i <= 2; i++)); do
 python3 test_0$i.py; done
cd ~/bash

从 python 目录中提取 test_0x.py 文件并按顺序运行它们。 test_01.py 是单个打印语句,而 test_02 是 for 循环。

我期待它:

  1. 导航到〜/ python
  2. 运行test_01.py
  3. 运行test_02.py
  4. 导航回 ~/bash

bash 脚本运行 test_01.py,然后运行 test_01.py 再次,然后才运行 test_02.py。 这是 shell 脚本的一些怪癖吗?我太新了,无法预料,或者我的代码(尽管非常基本)有问题吗?

我正在通过 Linux 的 Windows 子系统使用 ubuntu 终端,如果这会影响的话。

bash shell ubuntu unix windows-subsystem-for-linux
1个回答
0
投票

在这种情况下运行 WSL 应该不会产生任何影响。

您的脚本存在一些问题,但至少那些可见的问题不会导致额外的循环。

要调试问题的loop部分,我会从以下开始:

  1. 从命令行,在同一目录中运行相同的循环,但使用

    echo
    代替 Python 调用本身:

    cd ~/python
    for ((i = 1; i <= 2; i++)); do
      echo test_0$i.py; done
    
  2. 如果有效,请对脚本进行相同的调整并测试它。

  3. 如果有效,如评论中所述,请检查

    test_01.py
    以查看它是否正在调用
    test_02.py
    。尝试在命令行手动运行它和/或目视检查它。


其他问题

  • 您的shebang行中有一个拼写错误(至少当您在问题中输入时)-

    #! usr/bin/env bash
    。 shebang 行的目的是告诉系统哪个程序应该执行您的脚本(例如,当称为
    ./script.sh
    时)。这根本行不通。

    正确的 shebang 线是:

    #!/usr/bin/env bash
    
  • 但是,如果您确实希望它作为脚本运行,那么我们将讨论第二个问题。您提到第 4 步应该是 “导航回 ~/bash”

    通过 shebang 行执行脚本时,这不会产生“预期效果”。它可能“看起来”可以工作,但真正发生的情况是 shell 仍然位于它“启动”的目录中。这个可能~/bash目录,但也可能不是。例如: cd ~ ~/bash/script.sh 脚本完成后,您将返回到

    ~
    目录。

    为什么?使用 shebang 行时,脚本由单独的 shell 调用“执行”。 
    cd

    发生在

    this
    shell(作为子进程运行)内。由于

    cd

    是环境更改(PWD 环境变量),因此它无法传播回调用进程。 如果您确实需要脚本能够更改调用 shell 的目录(您可能不需要),那么您需要

    source
    脚本而不是
    执行 
    它。
    source script.sh
    将处理当前运行的 Bash shell

    内部

    的脚本,允许它更改当前 shell 的当前目录。

    
    
        
    
    
    
© www.soinside.com 2019 - 2024. All rights reserved.