【问题标题】:run OS command inside a directory在目录中运行 OS 命令
【发布时间】:2021-07-12 16:34:16
【问题描述】:

我有一个脚本,我首先在其中创建了一个文件夹(以 i 命名,即 for 循环中的列表元素)。然后我想使用 cd 进入创建的文件夹并在其中运行 wget 命令。

但是,目前 wget 命令在根文件夹中运行并下载那里的所有文件(而不是导航到该文件夹​​然后下载其中的文件)

也许我必须在创建文件夹之前设置一个计时器或等待?我该如何解决这个问题并在创建的文件夹中运行 wget 命令

import os
lst = ['www.sr-line.com','www.montratec.com']

for i in lst:
    print(i)
    os.system('mkdir %s' % i)
    os.system('cd %s' % i)
    #os.system('mkdir test')
    os.system('wget -A pdf -m -p -E -k -K -nd %s' % i)
    os.system('cd ..')

【问题讨论】:

  • 您在做这些事情时遇到了什么问题?我不明白你的问题是什么,或者你没有说清楚!
  • 我想进入一个文件夹,然后在该文件夹中运行 os.system('wget -A pdf -m -p -E -k -K -nd %s' % i),然后返回主文件夹。目前,它只运行 wget 命令并将文件下载到脚本所在的主文件夹中。现在这有意义吗? @Kshitiz
  • os.system("cd test ; wget ...")
  • 由于我使用 % I 作为字符串,您能帮我解决语法问题吗?这给了我当前os.system('mkdir %s' % i; 'cd %s' % i; 'wget -A pdf -m -p -E -k -K -nd %s' % i; 'cd ..')@furas 的语法错误
  • 您必须将所有命令放在一个字符串中,并在此字符串中使用; - 并且在此字符串之后仅使用一个% - 喜欢"string" % (i, i, i) 或者您应该使用f-string 或@987654330 @

标签: python python-3.x wget python-os


【解决方案1】:

每个命令都在一个新的 shell 中执行,您需要将它们链接在一起:

import os
lst = ['www.sr-line.com', 'www.montratec.com']

for i in lst:
    command = f'mkdir -p /tmp/{i}; cd /tmp/{i}; wget -A pdf -m -p -E -k -K -nd {i}'
    os.system(command)

【讨论】:

  • 需要加tmp吗?
  • 没有。我更喜欢使用完整路径来了解保存的内容...取决于您如何执行脚本看看我的答案there
  • 不,我认为您不必添加/temp/{i},您可以只添加/{i}
  • 还有,什么是fll?
  • @x89: 错字,已修复:)
【解决方案2】:

在您的示例中,您可以使用直接 Python 操作,而不是为每个命令启动一个 shell。这可以提供更具可读性和更快的代码。例如(详见documentation of Python standard library),在Linux上(未经测试的代码):

 os.mkdir(i)
 oldwd = os.getcwd()
 os.chdir(i)
 os.system('wget -A pdf -m -p -E -k -K -nd %s' % i)
 os.chdir(oldwd)

你甚至不需要 fork wget 命令(甚至可能没有安装该程序)...你可以使用来自 os.urllib 的设施

请记住,启动一个新进程是一项非常昂贵的操作(您的操作系统可能会因此而失败:在 Linux 上,请参阅 fork(2)syscalls(2)errno(3)...)

【讨论】:

  • 现在,它给了我SyntaxError: invalid syntaxvar oldwd
  • 删除var
【解决方案3】:

您可以运行将多个命令放在一个以; 分隔的字符串中。

os.system("mkdir test ; cd test ; wget ...")

如果命令需要使用参数,那么你应该只使用一个% 和所有值的列表/元组

os.system('mkdir %s ; cd %s ; wget -A pdf -m -p -E -k -K -nd %s ; cd ..' % (i, i, i) )

或者你应该使用.format()

os.system('mkdir {} ; cd {} ; wget -A pdf -m -p -E -k -K -nd {} ; cd ..'.format(i, i, i))

但更简单的是使用f-string

os.system(f'mkdir {i} ; cd {i} ; wget -A pdf -m -p -E -k -K -nd {i} ; cd ..')

编辑:

最终,您可以单独创建每个命令,然后将它们连接起来 - 使用列表可以更简单

all_cmds = [
   'mkdir %s' % i,
   'cd %s' % i,
   'wget -A pdf -m -p -E -k -K -nd %s' % i,
   'cd ..'
]

cmd = ';'.join(all_cmds)

如果您想使用if/else 跳过某些元素,它会很有用

create_subfolder = True # False

all_cmds = []

if create_subfolder:
   all_cmds.append( 'mkdir %s' % i )
   all_cmds.append( 'cd %s' % i )

all_cmds.append( 'wget -A pdf -m -p -E -k -K -nd %s' % i )

if create_subfolder:
   all_cmds.append( 'cd ..' )

cmd = ';'.join(all_cmds)

顺便说一句:

此方法也可用于在单个命令中添加或跳过参数

cmd = ['wget']

if some_parameter:
    #cmd.append('-A pdf')
    #cmd.extend(['-A', 'pdf']) 
    cmd += ['-A', 'pdf'] 

cmd += ['-m', '-p', '-E', '-k', '-K', '-nd', i] # directly `i` without `%s`

cmd = ' '.join(cmd)  # join with spaces

【讨论】:

    【解决方案4】:

    运行system() 将启动一个新进程。该进程的作用不会影响父进程,因此那里的目录更改不会影响其他任何其他进程,包括由同一父进程启动的兄弟进程。

    只需告诉wget 在哪里存储东西或在影响wget 的进程中执行目录更改,例如父母。

    【讨论】:

    • 你能帮我如何制定命令吗? os.system('mkdir %s' % i; 'cd %s' % i; 'wget -A pdf -m -p -E -k -K -nd %s' % i; 'cd ..') 这给了我一个语法错误现在
    • 这与命令无关,您的字符串格式已关闭。请记住,Python 和您生成的 shell 代码都使用引号。从小处着手,然后扩展。
    猜你喜欢
    • 1970-01-01
    • 2012-11-13
    • 1970-01-01
    • 2012-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-27
    • 1970-01-01
    相关资源
    最近更新 更多