Hướng dẫn run bash command in python - chạy lệnh bash trong python

Để phần nào mở rộng trên các câu trả lời trước đây ở đây, có một số chi tiết thường bị bỏ qua.

Show
  • Thích
    # XXX AVOID THIS BUG
    buggy = subprocess.run('dig +short stackoverflow.com')
    
    # XXX AVOID THIS BUG TOO
    broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        shell=True)
    
    # XXX DEFINITELY AVOID THIS
    pathological = subprocess.run(['dig +short stackoverflow.com'],
        shell=True)
    
    correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        # Probably don't forget these, too
        check=True, text=True)
    
    # XXX Probably better avoid shell=True
    # but this is nominally correct
    fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
        shell=True,
        # Probably don't forget these, too
        check=True, text=True)
    
    0 hơn
    # XXX AVOID THIS BUG
    buggy = subprocess.run('dig +short stackoverflow.com')
    
    # XXX AVOID THIS BUG TOO
    broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        shell=True)
    
    # XXX DEFINITELY AVOID THIS
    pathological = subprocess.run(['dig +short stackoverflow.com'],
        shell=True)
    
    correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        # Probably don't forget these, too
        check=True, text=True)
    
    # XXX Probably better avoid shell=True
    # but this is nominally correct
    fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
        shell=True,
        # Probably don't forget these, too
        check=True, text=True)
    
    1 và bạn bè hơn
    # XXX AVOID THIS BUG
    buggy = subprocess.run('dig +short stackoverflow.com')
    
    # XXX AVOID THIS BUG TOO
    broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        shell=True)
    
    # XXX DEFINITELY AVOID THIS
    pathological = subprocess.run(['dig +short stackoverflow.com'],
        shell=True)
    
    correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        # Probably don't forget these, too
        check=True, text=True)
    
    # XXX Probably better avoid shell=True
    # but this is nominally correct
    fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
        shell=True,
        # Probably don't forget these, too
        check=True, text=True)
    
    2 hơn
    # XXX AVOID THIS BUG
    buggy = subprocess.run('dig +short stackoverflow.com')
    
    # XXX AVOID THIS BUG TOO
    broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        shell=True)
    
    # XXX DEFINITELY AVOID THIS
    pathological = subprocess.run(['dig +short stackoverflow.com'],
        shell=True)
    
    correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        # Probably don't forget these, too
        check=True, text=True)
    
    # XXX Probably better avoid shell=True
    # but this is nominally correct
    fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
        shell=True,
        # Probably don't forget these, too
        check=True, text=True)
    
    3 hơn
    # XXX AVOID THIS BUG
    buggy = subprocess.run('dig +short stackoverflow.com')
    
    # XXX AVOID THIS BUG TOO
    broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        shell=True)
    
    # XXX DEFINITELY AVOID THIS
    pathological = subprocess.run(['dig +short stackoverflow.com'],
        shell=True)
    
    correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        # Probably don't forget these, too
        check=True, text=True)
    
    # XXX Probably better avoid shell=True
    # but this is nominally correct
    fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
        shell=True,
        # Probably don't forget these, too
        check=True, text=True)
    
    4 hơn
    # XXX AVOID THIS BUG
    buggy = subprocess.run('dig +short stackoverflow.com')
    
    # XXX AVOID THIS BUG TOO
    broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        shell=True)
    
    # XXX DEFINITELY AVOID THIS
    pathological = subprocess.run(['dig +short stackoverflow.com'],
        shell=True)
    
    correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        # Probably don't forget these, too
        check=True, text=True)
    
    # XXX Probably better avoid shell=True
    # but this is nominally correct
    fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
        shell=True,
        # Probably don't forget these, too
        check=True, text=True)
    
    5
  • Hiểu và có thể sử dụng
    # XXX AVOID THIS BUG
    buggy = subprocess.run('dig +short stackoverflow.com')
    
    # XXX AVOID THIS BUG TOO
    broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        shell=True)
    
    # XXX DEFINITELY AVOID THIS
    pathological = subprocess.run(['dig +short stackoverflow.com'],
        shell=True)
    
    correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        # Probably don't forget these, too
        check=True, text=True)
    
    # XXX Probably better avoid shell=True
    # but this is nominally correct
    fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
        shell=True,
        # Probably don't forget these, too
        check=True, text=True)
    
    6, AKA
    # XXX AVOID THIS BUG
    buggy = subprocess.run('dig +short stackoverflow.com')
    
    # XXX AVOID THIS BUG TOO
    broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        shell=True)
    
    # XXX DEFINITELY AVOID THIS
    pathological = subprocess.run(['dig +short stackoverflow.com'],
        shell=True)
    
    correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        # Probably don't forget these, too
        check=True, text=True)
    
    # XXX Probably better avoid shell=True
    # but this is nominally correct
    fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
        shell=True,
        # Probably don't forget these, too
        check=True, text=True)
    
    7.
  • Hiểu ý nghĩa của
    # XXX AVOID THIS BUG
    buggy = subprocess.run('dig +short stackoverflow.com')
    
    # XXX AVOID THIS BUG TOO
    broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        shell=True)
    
    # XXX DEFINITELY AVOID THIS
    pathological = subprocess.run(['dig +short stackoverflow.com'],
        shell=True)
    
    correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        # Probably don't forget these, too
        check=True, text=True)
    
    # XXX Probably better avoid shell=True
    # but this is nominally correct
    fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
        shell=True,
        # Probably don't forget these, too
        check=True, text=True)
    
    8 hoặc
    # XXX AVOID THIS BUG
    buggy = subprocess.run('dig +short stackoverflow.com')
    
    # XXX AVOID THIS BUG TOO
    broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        shell=True)
    
    # XXX DEFINITELY AVOID THIS
    pathological = subprocess.run(['dig +short stackoverflow.com'],
        shell=True)
    
    correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        # Probably don't forget these, too
        check=True, text=True)
    
    # XXX Probably better avoid shell=True
    # but this is nominally correct
    fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
        shell=True,
        # Probably don't forget these, too
        check=True, text=True)
    
    9 và cách nó thay đổi trích dẫn và sự sẵn có của các tiện ích shell.
  • Hiểu sự khác biệt giữa
    subprocess.run("string for 'the shell' to parse", shell=True)
    # or
    subprocess.run(["list", "of", "tokenized strings"]) # shell=False
    
    0 và bash
  • Hiểu làm thế nào một quy trình con tách biệt với cha mẹ của nó và thường không thể thay đổi cha mẹ.
  • Tránh chạy thông dịch viên Python như một quy trình con của Python.

Những chủ đề này được đề cập trong một số chi tiết hơn dưới đây.

Thích # XXX AVOID THIS BUG buggy = subprocess.run('dig +short stackoverflow.com') # XXX AVOID THIS BUG TOO broken = subprocess.run(['dig', '+short', 'stackoverflow.com'], shell=True) # XXX DEFINITELY AVOID THIS pathological = subprocess.run(['dig +short stackoverflow.com'], shell=True) correct = subprocess.run(['dig', '+short', 'stackoverflow.com'], # Probably don't forget these, too check=True, text=True) # XXX Probably better avoid shell=True # but this is nominally correct fixed_but_fugly = subprocess.run('dig +short stackoverflow.com', shell=True, # Probably don't forget these, too check=True, text=True) 0 hoặc # XXX AVOID THIS BUG buggy = subprocess.run('dig +short stackoverflow.com') # XXX AVOID THIS BUG TOO broken = subprocess.run(['dig', '+short', 'stackoverflow.com'], shell=True) # XXX DEFINITELY AVOID THIS pathological = subprocess.run(['dig +short stackoverflow.com'], shell=True) correct = subprocess.run(['dig', '+short', 'stackoverflow.com'], # Probably don't forget these, too check=True, text=True) # XXX Probably better avoid shell=True # but this is nominally correct fixed_but_fugly = subprocess.run('dig +short stackoverflow.com', shell=True, # Probably don't forget these, too check=True, text=True) 1

Hàm

# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)
3 là một công việc ở mức độ thấp nhưng thật khó để sử dụng chính xác và bạn kết thúc việc sao chép/dán nhiều dòng mã ... đã tồn tại thuận tiện trong thư viện tiêu chuẩn như một tập hợp các chức năng trình bao tải cấp cao hơn cho các mục đích khác nhau , được trình bày chi tiết hơn trong phần sau.

Đây là một đoạn từ tài liệu:

Cách tiếp cận được đề xuất để gọi các quy trình con là sử dụng chức năng

subprocess.run("string for 'the shell' to parse", shell=True)
# or
subprocess.run(["list", "of", "tokenized strings"]) # shell=False
4 cho tất cả các trường hợp sử dụng mà nó có thể xử lý. Đối với các trường hợp sử dụng nâng cao hơn, giao diện
subprocess.run("string for 'the shell' to parse", shell=True)
# or
subprocess.run(["list", "of", "tokenized strings"]) # shell=False
5 cơ bản có thể được sử dụng trực tiếp.

Thật không may, sự sẵn có của các chức năng trình bao bọc này khác nhau giữa các phiên bản Python.

  • # XXX AVOID THIS BUG
    buggy = subprocess.run('dig +short stackoverflow.com')
    
    # XXX AVOID THIS BUG TOO
    broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        shell=True)
    
    # XXX DEFINITELY AVOID THIS
    pathological = subprocess.run(['dig +short stackoverflow.com'],
        shell=True)
    
    correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        # Probably don't forget these, too
        check=True, text=True)
    
    # XXX Probably better avoid shell=True
    # but this is nominally correct
    fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
        shell=True,
        # Probably don't forget these, too
        check=True, text=True)
    
    0 đã được chính thức giới thiệu trong Python 3.5. Nó có nghĩa là để thay thế tất cả những điều sau đây.
  • subprocess.run("string for 'the shell' to parse", shell=True)
    # or
    subprocess.run(["list", "of", "tokenized strings"]) # shell=False
    
    7 đã được giới thiệu trong Python 2.7 / 3.1. Về cơ bản nó tương đương với
    subprocess.run("string for 'the shell' to parse", shell=True)
    # or
    subprocess.run(["list", "of", "tokenized strings"]) # shell=False
    
    8
  • # XXX AVOID THIS BUG
    buggy = subprocess.run('dig +short stackoverflow.com')
    
    # XXX AVOID THIS BUG TOO
    broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        shell=True)
    
    # XXX DEFINITELY AVOID THIS
    pathological = subprocess.run(['dig +short stackoverflow.com'],
        shell=True)
    
    correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        # Probably don't forget these, too
        check=True, text=True)
    
    # XXX Probably better avoid shell=True
    # but this is nominally correct
    fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
        shell=True,
        # Probably don't forget these, too
        check=True, text=True)
    
    1 đã được giới thiệu trong Python 2.5. Về cơ bản nó tương đương với
    subprocess.run(shlex.split("no string for 'the shell' to parse"))  # shell=False
    # equivalent to
    # subprocess.run(["no", "string", "for", "the shell", "to", "parse"])
    
    0
  • # XXX AVOID THIS BUG
    buggy = subprocess.run('dig +short stackoverflow.com')
    
    # XXX AVOID THIS BUG TOO
    broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        shell=True)
    
    # XXX DEFINITELY AVOID THIS
    pathological = subprocess.run(['dig +short stackoverflow.com'],
        shell=True)
    
    correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        # Probably don't forget these, too
        check=True, text=True)
    
    # XXX Probably better avoid shell=True
    # but this is nominally correct
    fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
        shell=True,
        # Probably don't forget these, too
        check=True, text=True)
    
    2 đã được giới thiệu trong Python 2.4 trong mô-đun
    subprocess.run(shlex.split("no string for 'the shell' to parse"))  # shell=False
    # equivalent to
    # subprocess.run(["no", "string", "for", "the shell", "to", "parse"])
    
    2 ban đầu (PEP-324). Về cơ bản nó tương đương với
    subprocess.run(shlex.split("no string for 'the shell' to parse"))  # shell=False
    # equivalent to
    # subprocess.run(["no", "string", "for", "the shell", "to", "parse"])
    
    3

API cấp cao so với # XXX AVOID THIS BUG buggy = subprocess.run('dig +short stackoverflow.com') # XXX AVOID THIS BUG TOO broken = subprocess.run(['dig', '+short', 'stackoverflow.com'], shell=True) # XXX DEFINITELY AVOID THIS pathological = subprocess.run(['dig +short stackoverflow.com'], shell=True) correct = subprocess.run(['dig', '+short', 'stackoverflow.com'], # Probably don't forget these, too check=True, text=True) # XXX Probably better avoid shell=True # but this is nominally correct fixed_but_fugly = subprocess.run('dig +short stackoverflow.com', shell=True, # Probably don't forget these, too check=True, text=True) 3

____10 được tái cấu trúc và mở rộng là hợp lý và linh hoạt hơn so với các chức năng di sản cũ mà nó thay thế. Nó trả về một đối tượng

subprocess.run(shlex.split("no string for 'the shell' to parse"))  # shell=False
# equivalent to
# subprocess.run(["no", "string", "for", "the shell", "to", "parse"])
6 có nhiều phương pháp khác nhau cho phép bạn truy xuất trạng thái thoát, đầu ra tiêu chuẩn và một vài kết quả và chỉ số trạng thái khác từ quy trình con đã hoàn thành.

# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)
0 là cách để đi nếu bạn chỉ cần một chương trình để chạy và trả lại quyền kiểm soát cho Python. Để biết thêm các kịch bản liên quan (các quy trình nền, có lẽ với I/O tương tác với chương trình phụ huynh Python), bạn vẫn cần sử dụng
# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)
3 và tự mình chăm sóc tất cả các hệ thống ống nước. Điều này đòi hỏi một sự hiểu biết khá phức tạp về tất cả các bộ phận chuyển động và không nên được thực hiện một cách nhẹ nhàng. Đối tượng
subprocess.run("string for 'the shell' to parse", shell=True)
# or
subprocess.run(["list", "of", "tokenized strings"]) # shell=False
5 đơn giản hơn đại diện cho quá trình (có thể là vẫn còn) cần được quản lý từ mã của bạn trong phần còn lại của vòng đời của quá trình phụ.

Có lẽ nên nhấn mạnh rằng chỉ

# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)
3 chỉ tạo ra một quá trình. Nếu bạn để nó ở đó, bạn có một quy trình con chạy đồng thời cùng với Python, vì vậy một quá trình "nền". Nếu nó không cần phải thực hiện đầu vào hoặc đầu ra hoặc phối hợp với bạn, nó có thể thực hiện công việc hữu ích song song với chương trình Python của bạn.

Tránh # XXX AVOID THIS BUG buggy = subprocess.run('dig +short stackoverflow.com') # XXX AVOID THIS BUG TOO broken = subprocess.run(['dig', '+short', 'stackoverflow.com'], shell=True) # XXX DEFINITELY AVOID THIS pathological = subprocess.run(['dig +short stackoverflow.com'], shell=True) correct = subprocess.run(['dig', '+short', 'stackoverflow.com'], # Probably don't forget these, too check=True, text=True) # XXX Probably better avoid shell=True # but this is nominally correct fixed_but_fugly = subprocess.run('dig +short stackoverflow.com', shell=True, # Probably don't forget these, too check=True, text=True) 4 và # XXX AVOID THIS BUG buggy = subprocess.run('dig +short stackoverflow.com') # XXX AVOID THIS BUG TOO broken = subprocess.run(['dig', '+short', 'stackoverflow.com'], shell=True) # XXX DEFINITELY AVOID THIS pathological = subprocess.run(['dig +short stackoverflow.com'], shell=True) correct = subprocess.run(['dig', '+short', 'stackoverflow.com'], # Probably don't forget these, too check=True, text=True) # XXX Probably better avoid shell=True # but this is nominally correct fixed_but_fugly = subprocess.run('dig +short stackoverflow.com', shell=True, # Probably don't forget these, too check=True, text=True) 5

Kể từ thời gian vĩnh cửu (tốt, kể từ Python 2.5), tài liệu mô -đun

cmd = '''while read -r x;
   do ping -c 3 "$x" | grep 'min/avg/max'
   done 
3 đã chứa khuyến nghị để thích
subprocess.run(shlex.split("no string for 'the shell' to parse"))  # shell=False
# equivalent to
# subprocess.run(["no", "string", "for", "the shell", "to", "parse"])
2 hơn
# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)
4:

Mô -đun

subprocess.run(shlex.split("no string for 'the shell' to parse"))  # shell=False
# equivalent to
# subprocess.run(["no", "string", "for", "the shell", "to", "parse"])
2 cung cấp các cơ sở mạnh mẽ hơn để sinh ra các quy trình mới và truy xuất kết quả của chúng; Sử dụng mô -đun đó là thích hợp hơn để sử dụng chức năng này.

Các vấn đề với

cmd = '''while read -r x;
   do ping -c 3 "$x" | grep 'min/avg/max'
   done 
7 là nó rõ ràng phụ thuộc vào hệ thống và không cung cấp các cách để tương tác với quy trình con. Nó chỉ đơn giản là chạy, với đầu ra tiêu chuẩn và lỗi tiêu chuẩn ngoài tầm với của Python. Thông tin duy nhất Python nhận lại là trạng thái thoát của lệnh (0 có nghĩa là thành công, mặc dù ý nghĩa của các giá trị khác không cũng phụ thuộc vào hệ thống).

PEP-324 (đã được đề cập ở trên) chứa một lý do chi tiết hơn về lý do tại sao

cmd = '''while read -r x;
   do ping -c 3 "$x" | grep 'min/avg/max'
   done 
8 là vấn đề và cách
subprocess.run(shlex.split("no string for 'the shell' to parse"))  # shell=False
# equivalent to
# subprocess.run(["no", "string", "for", "the shell", "to", "parse"])
2 cố gắng giải quyết các vấn đề đó.

# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)
5 đã từng nản lòng hơn nữa:

Không dùng nữa vì phiên bản 2.6: Hàm này đã lỗi thời. Sử dụng mô -đun

subprocess.run(shlex.split("no string for 'the shell' to parse"))  # shell=False
# equivalent to
# subprocess.run(["no", "string", "for", "the shell", "to", "parse"])
2.

Tuy nhiên, vì đôi khi trong Python 3, nó đã được thực hiện lại khi chỉ sử dụng

subprocess.run(shlex.split("no string for 'the shell' to parse"))  # shell=False
# equivalent to
# subprocess.run(["no", "string", "for", "the shell", "to", "parse"])
2 và chuyển hướng đến tài liệu
# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)
3 để biết chi tiết.

Hiểu và thường sử dụng subprocess.run(''' # This for loop syntax is Bash only for((i=1;i<=$#;i++)); do # Arrays are Bash-only array[i]+=123 done''', shell=True, check=True, executable='/bin/bash') 4

Bạn cũng sẽ nhận thấy rằng

# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)
2 có nhiều hạn chế tương tự như
# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)
4. Khi sử dụng thường xuyên, bạn thường nên kiểm tra xem quá trình đã hoàn thành thành công, mà
# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)
1 và
subprocess.run("string for 'the shell' to parse", shell=True)
# or
subprocess.run(["list", "of", "tokenized strings"]) # shell=False
7 có (trong đó quá trình sau cũng trả về đầu ra tiêu chuẩn của quá trình phụ hoàn thành). Tương tự, bạn thường nên sử dụng
subprocess.run('''
    # This for loop syntax is Bash only
    for((i=1;i<=$#;i++)); do
        # Arrays are Bash-only
        array[i]+=123
    done''',
    shell=True, check=True,
    executable='/bin/bash')
4 với
# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)
0 trừ khi bạn cụ thể cần cho phép quy trình con trả về trạng thái lỗi.

Trong thực tế, với

subprocess.run('''
    # This for loop syntax is Bash only
    for((i=1;i<=$#;i++)); do
        # Arrays are Bash-only
        array[i]+=123
    done''',
    shell=True, check=True,
    executable='/bin/bash')
4 hoặc
subprocess.run('cd /tmp', shell=True)
subprocess.run('pwd', shell=True)  # Oops, doesn't print /tmp
2, Python sẽ ném ngoại lệ
subprocess.run('cd /tmp', shell=True)
subprocess.run('pwd', shell=True)  # Oops, doesn't print /tmp
3 nếu quá trình phụ trả về trạng thái thoát khác không.

Một lỗi phổ biến với

# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)
0 là bỏ qua
subprocess.run('''
    # This for loop syntax is Bash only
    for((i=1;i<=$#;i++)); do
        # Arrays are Bash-only
        array[i]+=123
    done''',
    shell=True, check=True,
    executable='/bin/bash')
4 và sẽ ngạc nhiên khi mã xuôi dòng không thành công nếu quá trình phụ thất bại.

Mặt khác, một vấn đề phổ biến với

subprocess.run('cd /tmp', shell=True)
subprocess.run('pwd', shell=True)  # Oops, doesn't print /tmp
6 và
subprocess.run('cd /tmp', shell=True)
subprocess.run('pwd', shell=True)  # Oops, doesn't print /tmp
7 là người dùng sử dụng một cách mù quáng các chức năng này đã rất ngạc nhiên khi ngoại lệ được nêu ra, ví dụ: Khi
subprocess.run('cd /tmp', shell=True)
subprocess.run('pwd', shell=True)  # Oops, doesn't print /tmp
8 không tìm thấy một trận đấu. (Có lẽ bạn nên thay thế
subprocess.run('cd /tmp', shell=True)
subprocess.run('pwd', shell=True)  # Oops, doesn't print /tmp
8 bằng mã Python gốc, như được nêu dưới đây.)

Tất cả mọi thứ được tính, bạn cần hiểu cách các lệnh shell trả về mã thoát và trong những điều kiện nào chúng sẽ trả lại mã thoát khác không (lỗi) và đưa ra quyết định có ý thức về cách xử lý chính xác.

Hiểu và có thể sử dụng # XXX AVOID THIS BUG buggy = subprocess.run('dig +short stackoverflow.com') # XXX AVOID THIS BUG TOO broken = subprocess.run(['dig', '+short', 'stackoverflow.com'], shell=True) # XXX DEFINITELY AVOID THIS pathological = subprocess.run(['dig +short stackoverflow.com'], shell=True) correct = subprocess.run(['dig', '+short', 'stackoverflow.com'], # Probably don't forget these, too check=True, text=True) # XXX Probably better avoid shell=True # but this is nominally correct fixed_but_fugly = subprocess.run('dig +short stackoverflow.com', shell=True, # Probably don't forget these, too check=True, text=True) 6 aka # XXX AVOID THIS BUG buggy = subprocess.run('dig +short stackoverflow.com') # XXX AVOID THIS BUG TOO broken = subprocess.run(['dig', '+short', 'stackoverflow.com'], shell=True) # XXX DEFINITELY AVOID THIS pathological = subprocess.run(['dig +short stackoverflow.com'], shell=True) correct = subprocess.run(['dig', '+short', 'stackoverflow.com'], # Probably don't forget these, too check=True, text=True) # XXX Probably better avoid shell=True # but this is nominally correct fixed_but_fugly = subprocess.run('dig +short stackoverflow.com', shell=True, # Probably don't forget these, too check=True, text=True) 7

Kể từ Python 3, chuỗi bên trong Python là chuỗi Unicode. Nhưng không có gì đảm bảo rằng một quy trình con tạo ra đầu ra unicode hoặc chuỗi.

. )

Sâu thẳm, Python phải lấy bộ đệm

subprocess.run('cd /tmp; pwd', shell=True)
2 và giải thích nó bằng cách nào đó. Nếu nó chứa một đốm dữ liệu nhị phân, nó không nên được giải mã thành một chuỗi unicode, bởi vì đó là hành vi dễ bị lỗi và gây lỗi-chính xác là loại hành vi phiền phức đã đánh đố nhiều tập lệnh Python 2, trước khi có cách nào Phân biệt đúng giữa văn bản được mã hóa và dữ liệu nhị phân.

Với

# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)
6, bạn nói với Python rằng trên thực tế, bạn mong đợi dữ liệu văn bản trở lại trong mã hóa mặc định của hệ thống và nó nên được giải mã thành chuỗi python (unicode) với khả năng của Python tốt nhất (thường là UTF-8 trên bất kỳ đến ngày hệ thống, ngoại trừ có lẽ là Windows?)

Nếu đó không phải là những gì bạn yêu cầu trở lại, Python sẽ chỉ cung cấp cho bạn các chuỗi ____72 trong chuỗi

subprocess.run('cd /tmp; pwd', shell=True)
5 và
subprocess.run('cd /tmp; pwd', shell=True)
6. Có thể tại một số điểm sau bạn biết rằng chúng là chuỗi văn bản, và bạn biết mã hóa của chúng. Sau đó, bạn có thể giải mã chúng.

normal = subprocess.run([external, arg],
    stdout=subprocess.PIPE, stderr=subprocess.PIPE,
    check=True,
    text=True)
print(normal.stdout)

convoluted = subprocess.run([external, arg],
    stdout=subprocess.PIPE, stderr=subprocess.PIPE,
    check=True)
# You have to know (or guess) the encoding
print(convoluted.stdout.decode('utf-8'))

Python 3.7 đã giới thiệu bí danh ngắn hơn và mô tả hơn và dễ hiểu hơn

subprocess.run('cd /tmp; pwd', shell=True)
7 cho đối số từ khóa mà trước đây có phần gây hiểu lầm
subprocess.run('cd /tmp; pwd', shell=True)
8.

Hiểu # XXX AVOID THIS BUG buggy = subprocess.run('dig +short stackoverflow.com') # XXX AVOID THIS BUG TOO broken = subprocess.run(['dig', '+short', 'stackoverflow.com'], shell=True) # XXX DEFINITELY AVOID THIS pathological = subprocess.run(['dig +short stackoverflow.com'], shell=True) correct = subprocess.run(['dig', '+short', 'stackoverflow.com'], # Probably don't forget these, too check=True, text=True) # XXX Probably better avoid shell=True # but this is nominally correct fixed_but_fugly = subprocess.run('dig +short stackoverflow.com', shell=True, # Probably don't forget these, too check=True, text=True) 8 vs # XXX AVOID THIS BUG buggy = subprocess.run('dig +short stackoverflow.com') # XXX AVOID THIS BUG TOO broken = subprocess.run(['dig', '+short', 'stackoverflow.com'], shell=True) # XXX DEFINITELY AVOID THIS pathological = subprocess.run(['dig +short stackoverflow.com'], shell=True) correct = subprocess.run(['dig', '+short', 'stackoverflow.com'], # Probably don't forget these, too check=True, text=True) # XXX Probably better avoid shell=True # but this is nominally correct fixed_but_fugly = subprocess.run('dig +short stackoverflow.com', shell=True, # Probably don't forget these, too check=True, text=True) 9

Với

# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)
8, bạn chuyển một chuỗi duy nhất cho vỏ của bạn và vỏ lấy nó từ đó.

Với

# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)
9, bạn chuyển một danh sách các đối số cho HĐH, bỏ qua vỏ.

Khi bạn không có vỏ, bạn sẽ tiết kiệm một quy trình và loại bỏ một lượng phức tạp ẩn khá đáng kể, có thể hoặc không thể chứa các lỗi hoặc thậm chí các vấn đề bảo mật.

Mặt khác, khi bạn không có vỏ, bạn không chuyển hướng, mở rộng thẻ đại diện, kiểm soát công việc và một số lượng lớn các tính năng vỏ khác.

Một sai lầm phổ biến là sử dụng

# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)
8 và sau đó vẫn chuyển Python một danh sách các mã thông báo hoặc ngược lại. Điều này xảy ra trong một số trường hợp, nhưng thực sự không được xác định và có thể phá vỡ theo những cách thú vị.

# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)

Câu trả lời chung "nhưng nó hoạt động đối với tôi" không phải là một phản bác hữu ích trừ khi bạn hiểu chính xác trong hoàn cảnh nào nó có thể ngừng hoạt động.

Để tóm tắt ngắn gọn, việc sử dụng đúng trông giống như

subprocess.run("string for 'the shell' to parse", shell=True)
# or
subprocess.run(["list", "of", "tokenized strings"]) # shell=False

Nếu bạn muốn tránh vỏ nhưng quá lười biếng hoặc không chắc chắn làm thế nào để phân tích một chuỗi vào danh sách các mã thông báo, hãy lưu ý rằng

os.environ['foo'] = 'bar'
4 có thể làm điều này cho bạn.

subprocess.run(shlex.split("no string for 'the shell' to parse"))  # shell=False
# equivalent to
# subprocess.run(["no", "string", "for", "the shell", "to", "parse"])

os.environ['foo'] = 'bar'
5 thông thường sẽ không hoạt động ở đây, bởi vì nó không bảo tồn trích dẫn. Trong ví dụ trên, hãy chú ý cách
os.environ['foo'] = 'bar'
6 là một chuỗi duy nhất.

Ví dụ tái cấu trúc

Rất thường xuyên, các tính năng của vỏ có thể được thay thế bằng mã Python gốc. Các tập lệnh AWK hoặc

os.environ['foo'] = 'bar'
7 đơn giản có lẽ chỉ nên được dịch sang Python thay thế.

Để minh họa một phần điều này, đây là một ví dụ điển hình nhưng hơi ngớ ngẩn liên quan đến nhiều tính năng vỏ.

cmd = '''while read -r x;
   do ping -c 3 "$x" | grep 'min/avg/max'
   done 

Một số điều cần lưu ý ở đây:

  • Với
    # XXX AVOID THIS BUG
    buggy = subprocess.run('dig +short stackoverflow.com')
    
    # XXX AVOID THIS BUG TOO
    broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        shell=True)
    
    # XXX DEFINITELY AVOID THIS
    pathological = subprocess.run(['dig +short stackoverflow.com'],
        shell=True)
    
    correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        # Probably don't forget these, too
        check=True, text=True)
    
    # XXX Probably better avoid shell=True
    # but this is nominally correct
    fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
        shell=True,
        # Probably don't forget these, too
        check=True, text=True)
    
    9, bạn không cần trích dẫn mà vỏ yêu cầu xung quanh chuỗi. Đặt báo giá dù sao có lẽ là một lỗi.
  • Nó thường có ý nghĩa để chạy càng ít mã càng tốt trong một quy trình con. Điều này cho phép bạn kiểm soát nhiều hơn đối với việc thực thi từ trong mã Python của bạn.
  • Phải nói rằng, các đường ống vỏ phức tạp là tẻ nhạt và đôi khi khó khăn để tái tạo trong Python.

Mã được tái cấu trúc cũng minh họa cho bao nhiêu vỏ thực sự cho bạn với một cú pháp rất ngắn - để tốt hơn hoặc tồi tệ hơn. Python nói rõ ràng là tốt hơn so với tiềm ẩn nhưng mã Python khá dài dòng và được cho là phức tạp hơn điều này thực sự. Mặt khác, nó cung cấp một số điểm mà bạn có thể nắm quyền kiểm soát ở giữa một thứ khác, như được minh họa một cách tầm thường bởi sự nâng cao mà chúng ta có thể dễ dàng bao gồm tên máy chủ cùng với đầu ra lệnh shell. .

Cấu trúc vỏ chung

Để hoàn thiện, đây là những giải thích ngắn gọn về một số tính năng vỏ này và một số ghi chú về cách chúng có thể được thay thế bằng các cơ sở Python bản địa.

  • Globbing AKA Mở rộng thẻ đại diện có thể được thay thế bằng
    os.environ['foo'] = 'bar'
    
    9 hoặc rất thường xuyên với các so sánh chuỗi python đơn giản như
    subprocess.run('echo "$foo"', shell=True, env={'foo': 'bar'})
    
    0. Bash có nhiều cơ sở mở rộng khác như
    subprocess.run('echo "$foo"', shell=True, env={'foo': 'bar'})
    
    1 Mở rộng Brace và
    subprocess.run('echo "$foo"', shell=True, env={'foo': 'bar'})
    
    2 cũng như mở rộng Tilde (
    subprocess.run('echo "$foo"', shell=True, env={'foo': 'bar'})
    
    3 mở rộng sang thư mục nhà của bạn và nói chung là
    subprocess.run('echo "$foo"', shell=True, env={'foo': 'bar'})
    
    4 cho thư mục nhà của người dùng khác)
  • Các biến shell như
    subprocess.run('echo "$foo"', shell=True, env={'foo': 'bar'})
    
    5 hoặc
    subprocess.run('echo "$foo"', shell=True, env={'foo': 'bar'})
    
    6 đôi khi có thể được thay thế bằng các biến Python. Các biến shell được xuất có sẵn dưới dạng ví dụ:
    subprocess.run('echo "$foo"', shell=True, env={'foo': 'bar'})
    
    7 (Ý nghĩa của
    subprocess.run('echo "$foo"', shell=True, env={'foo': 'bar'})
    
    8 là cung cấp biến có sẵn cho các quy trình con - một biến không có sẵn cho các quy trình con rõ ràng sẽ không có sẵn để Python chạy như một quy trình con của shell hoặc ngược lại. Cho phép bạn xác định môi trường của quy trình con là từ điển, vì vậy đó là một cách để tạo biến Python có thể nhìn thấy cho một quy trình con). Với
    # XXX AVOID THIS BUG
    buggy = subprocess.run('dig +short stackoverflow.com')
    
    # XXX AVOID THIS BUG TOO
    broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        shell=True)
    
    # XXX DEFINITELY AVOID THIS
    pathological = subprocess.run(['dig +short stackoverflow.com'],
        shell=True)
    
    correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        # Probably don't forget these, too
        check=True, text=True)
    
    # XXX Probably better avoid shell=True
    # but this is nominally correct
    fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
        shell=True,
        # Probably don't forget these, too
        check=True, text=True)
    
    9, bạn sẽ cần hiểu cách xóa bất kỳ trích dẫn nào; Ví dụ:
    # XXX AVOID THIS BUG
    buggy = subprocess.run('dig +short stackoverflow.com')
    
    # XXX AVOID THIS BUG TOO
    broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        shell=True)
    
    # XXX DEFINITELY AVOID THIS
    pathological = subprocess.run(['dig +short stackoverflow.com'],
        shell=True)
    
    correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        # Probably don't forget these, too
        check=True, text=True)
    
    # XXX Probably better avoid shell=True
    # but this is nominally correct
    fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
        shell=True,
        # Probably don't forget these, too
        check=True, text=True)
    
    02 tương đương với
    # XXX AVOID THIS BUG
    buggy = subprocess.run('dig +short stackoverflow.com')
    
    # XXX AVOID THIS BUG TOO
    broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        shell=True)
    
    # XXX DEFINITELY AVOID THIS
    pathological = subprocess.run(['dig +short stackoverflow.com'],
        shell=True)
    
    correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        # Probably don't forget these, too
        check=True, text=True)
    
    # XXX Probably better avoid shell=True
    # but this is nominally correct
    fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
        shell=True,
        # Probably don't forget these, too
        check=True, text=True)
    
    03 mà không có trích dẫn xung quanh tên thư mục. .
  • Chuyển hướng cho phép bạn đọc từ một tệp làm đầu vào tiêu chuẩn của bạn và viết đầu ra tiêu chuẩn của bạn vào một tệp.
    # XXX AVOID THIS BUG
    buggy = subprocess.run('dig +short stackoverflow.com')
    
    # XXX AVOID THIS BUG TOO
    broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        shell=True)
    
    # XXX DEFINITELY AVOID THIS
    pathological = subprocess.run(['dig +short stackoverflow.com'],
        shell=True)
    
    correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        # Probably don't forget these, too
        check=True, text=True)
    
    # XXX Probably better avoid shell=True
    # but this is nominally correct
    fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
        shell=True,
        # Probably don't forget these, too
        check=True, text=True)
    
    05 Mở
    # XXX AVOID THIS BUG
    buggy = subprocess.run('dig +short stackoverflow.com')
    
    # XXX AVOID THIS BUG TOO
    broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        shell=True)
    
    # XXX DEFINITELY AVOID THIS
    pathological = subprocess.run(['dig +short stackoverflow.com'],
        shell=True)
    
    correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        # Probably don't forget these, too
        check=True, text=True)
    
    # XXX Probably better avoid shell=True
    # but this is nominally correct
    fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
        shell=True,
        # Probably don't forget these, too
        check=True, text=True)
    
    06 để viết và
    # XXX AVOID THIS BUG
    buggy = subprocess.run('dig +short stackoverflow.com')
    
    # XXX AVOID THIS BUG TOO
    broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        shell=True)
    
    # XXX DEFINITELY AVOID THIS
    pathological = subprocess.run(['dig +short stackoverflow.com'],
        shell=True)
    
    correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        # Probably don't forget these, too
        check=True, text=True)
    
    # XXX Probably better avoid shell=True
    # but this is nominally correct
    fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
        shell=True,
        # Probably don't forget these, too
        check=True, text=True)
    
    07 để đọc và chuyển nội dung của nó dưới dạng đầu vào tiêu chuẩn cho
    subprocess.run('cd /tmp', shell=True)
    subprocess.run('pwd', shell=True)  # Oops, doesn't print /tmp
    
    8, có đầu ra tiêu chuẩn sau đó hạ cánh trong
    # XXX AVOID THIS BUG
    buggy = subprocess.run('dig +short stackoverflow.com')
    
    # XXX AVOID THIS BUG TOO
    broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        shell=True)
    
    # XXX DEFINITELY AVOID THIS
    pathological = subprocess.run(['dig +short stackoverflow.com'],
        shell=True)
    
    correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        # Probably don't forget these, too
        check=True, text=True)
    
    # XXX Probably better avoid shell=True
    # but this is nominally correct
    fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
        shell=True,
        # Probably don't forget these, too
        check=True, text=True)
    
    06. Điều này thường không khó để thay thế bằng mã python gốc.
  • Đường ống là một hình thức chuyển hướng.
    # XXX AVOID THIS BUG
    buggy = subprocess.run('dig +short stackoverflow.com')
    
    # XXX AVOID THIS BUG TOO
    broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        shell=True)
    
    # XXX DEFINITELY AVOID THIS
    pathological = subprocess.run(['dig +short stackoverflow.com'],
        shell=True)
    
    correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        # Probably don't forget these, too
        check=True, text=True)
    
    # XXX Probably better avoid shell=True
    # but this is nominally correct
    fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
        shell=True,
        # Probably don't forget these, too
        check=True, text=True)
    
    10 chạy hai quy trình con, trong đó đầu ra tiêu chuẩn của
    # XXX AVOID THIS BUG
    buggy = subprocess.run('dig +short stackoverflow.com')
    
    # XXX AVOID THIS BUG TOO
    broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        shell=True)
    
    # XXX DEFINITELY AVOID THIS
    pathological = subprocess.run(['dig +short stackoverflow.com'],
        shell=True)
    
    correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        # Probably don't forget these, too
        check=True, text=True)
    
    # XXX Probably better avoid shell=True
    # but this is nominally correct
    fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
        shell=True,
        # Probably don't forget these, too
        check=True, text=True)
    
    11 là đầu vào tiêu chuẩn của
    # XXX AVOID THIS BUG
    buggy = subprocess.run('dig +short stackoverflow.com')
    
    # XXX AVOID THIS BUG TOO
    broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        shell=True)
    
    # XXX DEFINITELY AVOID THIS
    pathological = subprocess.run(['dig +short stackoverflow.com'],
        shell=True)
    
    correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        # Probably don't forget these, too
        check=True, text=True)
    
    # XXX Probably better avoid shell=True
    # but this is nominally correct
    fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
        shell=True,
        # Probably don't forget these, too
        check=True, text=True)
    
    12 (ở cấp độ HĐH, trong các hệ thống giống UNIX, đây là một tay cầm tệp duy nhất). Nếu bạn không thể thay thế một hoặc cả hai đầu của đường ống bằng mã python gốc, có lẽ hãy nghĩ về việc sử dụng vỏ, đặc biệt là nếu đường ống có nhiều hơn hai hoặc ba quy trình (mặc dù nhìn vào mô -đun
    # XXX AVOID THIS BUG
    buggy = subprocess.run('dig +short stackoverflow.com')
    
    # XXX AVOID THIS BUG TOO
    broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        shell=True)
    
    # XXX DEFINITELY AVOID THIS
    pathological = subprocess.run(['dig +short stackoverflow.com'],
        shell=True)
    
    correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        # Probably don't forget these, too
        check=True, text=True)
    
    # XXX Probably better avoid shell=True
    # but this is nominally correct
    fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
        shell=True,
        # Probably don't forget these, too
        check=True, text=True)
    
    13 trong thư viện tiêu chuẩn Python hoặc A A Số lượng đối thủ cạnh tranh bên thứ ba hiện đại và đa năng hơn).
  • Kiểm soát công việc cho phép bạn làm gián đoạn các công việc, chạy chúng ở chế độ nền, đưa chúng trở lại nền trước, v.v ... Các tín hiệu Unix cơ bản để dừng và tiếp tục một quy trình tất nhiên cũng có sẵn từ Python. Nhưng các công việc là một sự trừu tượng cao hơn trong vỏ liên quan đến các nhóm quy trình, v.v. mà bạn phải hiểu nếu bạn muốn làm điều gì đó như thế này từ Python.
  • Trích dẫn trong vỏ có khả năng gây nhầm lẫn cho đến khi bạn hiểu rằng mọi thứ về cơ bản là một chuỗi. Vì vậy,
    # XXX AVOID THIS BUG
    buggy = subprocess.run('dig +short stackoverflow.com')
    
    # XXX AVOID THIS BUG TOO
    broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        shell=True)
    
    # XXX DEFINITELY AVOID THIS
    pathological = subprocess.run(['dig +short stackoverflow.com'],
        shell=True)
    
    correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        # Probably don't forget these, too
        check=True, text=True)
    
    # XXX Probably better avoid shell=True
    # but this is nominally correct
    fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
        shell=True,
        # Probably don't forget these, too
        check=True, text=True)
    
    14 tương đương với
    # XXX AVOID THIS BUG
    buggy = subprocess.run('dig +short stackoverflow.com')
    
    # XXX AVOID THIS BUG TOO
    broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        shell=True)
    
    # XXX DEFINITELY AVOID THIS
    pathological = subprocess.run(['dig +short stackoverflow.com'],
        shell=True)
    
    correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
        # Probably don't forget these, too
        check=True, text=True)
    
    # XXX Probably better avoid shell=True
    # but this is nominally correct
    fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
        shell=True,
        # Probably don't forget these, too
        check=True, text=True)
    
    15 nhưng trích dẫn xung quanh nghĩa đen là hoàn toàn tùy chọn. Các chuỗi chưa được trích xuất có chứa các metacharacters shell trải qua mở rộng tham số, mã thông báo khoảng trắng và mở rộng thẻ đại diện; Báo giá kép Ngăn chặn mã thông báo khoảng trắng và mở rộng ký tự đại diện nhưng cho phép mở rộng tham số (thay thế biến, thay thế lệnh và xử lý dấu gạch chéo ngược). Điều này đơn giản về mặt lý thuyết nhưng có thể trở nên hoang mang, đặc biệt là khi có một số lớp giải thích (ví dụ như một lệnh shell từ xa).

Hiểu sự khác biệt giữa subprocess.run("string for 'the shell' to parse", shell=True) # or subprocess.run(["list", "of", "tokenized strings"]) # shell=False 0 và bash

subprocess.run(shlex.split("no string for 'the shell' to parse"))  # shell=False
# equivalent to
# subprocess.run(["no", "string", "for", "the shell", "to", "parse"])
2 chạy các lệnh shell của bạn với
# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)
18 trừ khi bạn yêu cầu cụ thể khác (ngoại trừ tất nhiên trên Windows, trong đó nó sử dụng giá trị của biến
# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)
19). Điều này có nghĩa là các tính năng chỉ khác nhau như mảng,
# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)
20, vv không có sẵn.

Nếu bạn cần sử dụng cú pháp chỉ dành cho Bash, bạn có thể truyền qua đường dẫn đến vỏ dưới dạng

# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)
21 (tất nhiên nếu Bash của bạn được cài đặt ở một nơi khác, bạn cần điều chỉnh đường dẫn).

subprocess.run('''
    # This for loop syntax is Bash only
    for((i=1;i<=$#;i++)); do
        # Arrays are Bash-only
        array[i]+=123
    done''',
    shell=True, check=True,
    executable='/bin/bash')

A subprocess.run(shlex.split("no string for 'the shell' to parse")) # shell=False # equivalent to # subprocess.run(["no", "string", "for", "the shell", "to", "parse"]) 2 tách biệt với cha mẹ của nó và không thể thay đổi nó

Một sai lầm hơi phổ biến là làm điều gì đó như

subprocess.run('cd /tmp', shell=True)
subprocess.run('pwd', shell=True)  # Oops, doesn't print /tmp

Điều tương tự sẽ xảy ra nếu quy trình con đầu tiên cố gắng thiết lập một biến môi trường, tất nhiên điều này sẽ biến mất khi bạn chạy một quy trình con khác, v.v.

Một quá trình con chạy hoàn toàn tách biệt với Python và khi nó kết thúc, Python không biết nó đã làm gì (ngoài các chỉ số mơ hồ mà nó có thể suy ra từ trạng thái thoát và đầu ra từ quá trình con). Một đứa trẻ nói chung không thể thay đổi môi trường của cha mẹ; Nó không thể đặt một biến, thay đổi thư mục làm việc, hoặc, bằng rất nhiều từ, giao tiếp với cha mẹ của nó mà không cần sự hợp tác từ cha mẹ.

Việc sửa chữa ngay lập tức trong trường hợp cụ thể này là chạy cả hai lệnh trong một quy trình con;

subprocess.run('cd /tmp; pwd', shell=True)

Mặc dù rõ ràng trường hợp sử dụng cụ thể này không hữu ích lắm; Thay vào đó, hãy sử dụng đối số từ khóa

# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)
23 hoặc đơn giản là
# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)
24 trước khi chạy quy trình con. Tương tự, để thiết lập một biến, bạn có thể điều khiển môi trường của quy trình hiện tại (và do đó cũng là con cái của nó) thông qua

os.environ['foo'] = 'bar'

hoặc chuyển một môi trường cài đặt cho một quy trình trẻ em với

subprocess.run('echo "$foo"', shell=True, env={'foo': 'bar'})

.

Đừng chạy Python từ Python

Đây là lời khuyên hơi đáng ngờ; Chắc chắn có những tình huống mà nó có ý nghĩa hoặc thậm chí là một yêu cầu tuyệt đối để điều hành trình thông dịch Python như một quy trình con từ một kịch bản Python. Nhưng rất thường xuyên, cách tiếp cận chính xác chỉ đơn giản là

# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)
27 Mô -đun Python khác vào tập lệnh gọi của bạn và gọi trực tiếp các chức năng của nó.

Nếu tập lệnh Python khác nằm dưới sự kiểm soát của bạn và nó không phải là một mô -đun, hãy xem xét biến nó thành một. (Câu trả lời này đã quá dài vì vậy tôi sẽ không đi sâu vào chi tiết ở đây.)

Nếu bạn cần song song, bạn có thể chạy các hàm Python trong các quy trình con với mô -đun

# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)
28. Ngoài ra còn có
# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)
29 chạy nhiều tác vụ trong một quy trình duy nhất (nhẹ hơn và giúp bạn kiểm soát nhiều hơn, nhưng cũng bị hạn chế hơn trong các luồng đó trong một quy trình được ghép nối chặt chẽ và liên kết với một Gil.)

Bạn có thể chạy bash trong Python?

Thực hiện một tập lệnh bash hiện có bằng mô -đun phụ Python.Chúng tôi cũng có thể thực hiện một tập lệnh Bash hiện có bằng mô -đun phụ Python.. We can also execute an existing a bash script using Python subprocess module.

Lệnh bash trong Python là gì?

Định nghĩa: Python là ngôn ngữ lập trình cấp cao được thiết kế để dễ đọc và đơn giản để thực hiện.Mặc dù Bash là một trình thông dịch ngôn ngữ lệnh tương thích SH thực thi các lệnh được đọc từ đầu vào tiêu chuẩn hoặc từ một tệp.an sh-compatible command language interpreter that executes commands read from the standard input or from a file.

Python có thể chạy lệnh thiết bị đầu cuối không?

Python cho phép bạn thực thi các lệnh shell, mà bạn có thể sử dụng để bắt đầu các chương trình khác hoặc quản lý tốt hơn các tập lệnh shell mà bạn sử dụng để tự động hóa.Tùy thuộc vào trường hợp sử dụng của chúng tôi, chúng tôi có thể sử dụng hệ điều hành.hệ thống (), quy trình con., which you can use to start other programs or better manage shell scripts that you use for automation. Depending on our use case, we can use os. system() , subprocess.

Tôi có thể chạy lệnh Linux trong Python không?

Cách thứ hai để chạy các lệnh Linux với Python là bằng cách sử dụng mô -đun phụ mới hơn.Mô -đun này cho phép bạn sinh ra các quy trình mới, kết nối với đường ống đầu vào/đầu ra/lỗi của chúng và có được mã trả lại của chúng.Nó được tạo ra để thay thế cả hai hệ điều hành.Hệ thống () và HĐH.using the newer subprocess module. This module allows you to spawn new processes, connect to their input/output/error pipes, and obtain their return codes. It was created to replace both os. system() and os.