【问题标题】:Converting a bash script into Python using subprocess module使用 subprocess 模块将 bash 脚本转换为 Python
【发布时间】:2020-08-08 04:06:39
【问题描述】:

我正在尝试将 bash 脚本转换为子进程,以便安排不同的参数。这是我原来的 bash 脚本:

#!/bin/sh

set -xe

export NVIDIA_VISIBLE_DEVICES=0
export CUDA_VISIBLE_DEVICES=0
export TF_CUDNN_RESET_RND_GEN_STATE=1

python3 -u DeepSpeech.py \
  --train_files /external_data/data_csvs/train.csv \
  --test_files  /external_data/data_csvs/test.csv \
  --dev_files  /external_data/data_csvs/dev.csv \
  --epochs 30 \
  --train_batch_size 32 \
  --dev_batch_size 32 \
  --test_batch_size 32 \
  --export_dir /external_data/deepspeech_models/ \
  --use_allow_growth  \
  --n_hidden 2048 \
  --train_cudnn  \
  --learning_rate 0.00005 \
  --dropout_rate 0.40 \
  --summary_dir /external_data/tensorboard_summaries/ \
  --checkpoint_dir /external_data/mozilla_release_chkpts/deepspeech-0.7.4-checkpoint/ | tee //tmp/external/deepspeech_models/progress.txt \
  "$@"

现在我正在尝试将其转换为具有以下内容的子流程:

    subprocess.Popen([
        'set', '-xe',
        'export', 'NVIDIA_VISIBLE_DEVICES=0',
        'export', 'CUDA_VISIBLE_DEVICES=0',
        'export', 'TF_CUDNN_RESET_RND_GEN_STATE=1',
        'python3', '-u', 'DeepSpeech.py',
        '--train_files', '/external_data/data_csvs/train.csv',
        '--test_files'  '/external_data/data_csvs/test.csv',
        '--dev_files', '/external_data/data_csvs/dev.csv',
        '--epochs', str(epochs),
        '--train_batch_size', str(trainbs),
        '--dev_batch_size', str(devbs),
        '--test_batch_size', str(testbs),
        '--export_dir', '/external_data/deepspeech_models/',
        '--use_allow_growth',  
        '--n_hidden', str(2048),
        '--train_cudnn',  
        '--learning_rate', str(lr),
        '--summary_dir', '/external_data/tensorboard_summaries/' 
        '--checkpoint_dir', '/external_data/mozilla_release_chkpts/deepspeech-0.7.4-checkpoint/', '|', 'tee', '/external_data/deepspeech_models/Deepspeech_progress.txt',
        '$@'], shell = True, cwd = '//DeepSpeech/', stdout = subprocess.PIPE, executable = '/bin/sh')

str() 值只是我在子流程中用作变量的值。

它运行没有错误,但没有任何反应。我错过了什么吗? bash 脚本配置运行良好。另外,当我运行脚本时如何将输出处理到标准输出?

【问题讨论】:

  • 你期待什么输出?你能在top看到这个过程吗?
  • @Dallan 我正在使用 tensorflow 训练神经网络。我应该看到一些模型进展和一些正在采取的步骤。该进程不在top 中也许我需要将“\”添加到我的子进程中?
  • 您在各个命令之间缺少;。现在,所有内容都作为参数传递给set
  • @Dallan 当然!好的。那些会作为单独的';'我的参数列表中的标记?
  • 你说:["command", "arg1", "arg2"], env={"VAR1": "val1", "VAR2": "val2"} 而不是"export VAR1=val1; export VAR2=val2; command arg1 arg2", shell=True,你可以很高兴地将shell 排除在外,默认False。除了在 shell 本身中,当您编写单行程序时,您可以通过将变量添加到其命令行来导出单个命令的变量。 IE。 VAR1=val1 VAR2=val2 command arg1 arg2 而不是 export 必须是由换行符或 ; 终止的单独命令。

标签: python bash subprocess sh popen


【解决方案1】:

this answer 一样,您需要用; 分隔各个命令。

在您的情况下,请尝试以下操作:

train_cmd = ['python3', '-u', 'DeepSpeech.py',
            '--train_files', '/external_data/data_csvs/train.csv',
            '--test_files'  '/external_data/data_csvs/test.csv',
            '--dev_files', '/external_data/data_csvs/dev.csv',
            '--epochs', str(epochs),
            '--train_batch_size', str(trainbs),
            '--dev_batch_size', str(devbs),
            '--test_batch_size', str(testbs),
            '--export_dir', '/external_data/deepspeech_models/',
            '--use_allow_growth',  
            '--n_hidden', str(2048),
            '--train_cudnn',  
            '--learning_rate', str(lr),
            '--summary_dir', '/external_data/tensorboard_summaries/' 
            '--checkpoint_dir', '/external_data/mozilla_release_chkpts/deepspeech-0.7.4-checkpoint/', '|', 'tee', '/external_data/deepspeech_models/Deepspeech_progress.txt',
            '$@']
cmds = ['set -xe', 
        'export NVIDIA_VISIBLE_DEVICES=0', 
        'export CUDA_VISIBLE_DEVICES=0',
        'export TF_CUDNN_RESET_RND_GEN_STATE=1',
        ' '.join(train_cmd)]
subprocess.Popen('; '.join(cmds), shell = True, cwd = '//DeepSpeech/', stdout = subprocess.PIPE, executable = '/bin/sh')

【讨论】:

  • 为什么在我原来的 bash 脚本中,我不需要分号?非常新的 bash 脚本,所以任何帮助表示赞赏。
  • @Coldchain9 bash 脚本只是将每个命令按顺序放入 shell,在换行符处拆分(\ 转义 python 命令中的换行符)。如果你想用一个命令在 shell 中运行它,你还必须用分号将它们连接起来。见:docstore.mik.ua/orelly/unix3/upt/ch28_16.htm
  • 这一切都非常有用。它现在正在启动并完成了一些启动过程,但随后我收到了 BrokenPipeError
  • 没关系。我通过删除 stdout 参数来修复它。 IT 现在正在运行和工作。非常感谢您的帮助。我很快就会接受答案。
猜你喜欢
  • 1970-01-01
  • 2011-02-19
  • 1970-01-01
  • 2015-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-29
  • 1970-01-01
相关资源
最近更新 更多