我有像下面這樣的 bash 腳本。當您運行它時,它會詢問您的姓名,然后向您打招呼:
#example.sh
printf "Hello, who is running this program? "
read -r USERNAME
echo Hi $USERNAME!

是否可以撰寫一個可以1.運行sh example.sh 2.回應python輸入名稱的提示,以及3.讀Hi Larry!回 Python的 Python 腳本?
并且只是為了澄清這是一種假設情況,因此修改 bash 腳本不是目標。謝謝!
uj5u.com熱心網友回復:
如果您知道外部腳本的所有答案,那么您可以subprocess.run()將所有答案(帶\n)作為一個字串使用和發送。
對于測驗,我使用腳本等待兩個值USERNAME和COLOR
#example.sh
printf "Hello, who is running this program? "
read -r USERNAME
echo Hi $USERNAME!
printf "What is your favorite color? "
read -r COLOR
echo I like $COLOR too!
我可以使用單個字串"Larry\nBlue\n"一次發送兩個值。
import subprocess
cmd = ['sh', 'example.sh']
p = subprocess.run(cmd, input="Larry\nBlue\n".encode(), stdout=subprocess.PIPE)
print( p.stdout.decode() )
它在開始時發送所有內容,外部腳本將第一行作為第一個答案,第二行作為第二個答案等。當它完成時,Python 可以獲得所有輸出 -
Hello, who is running this program? Hi Larry!
What is your favorite color? I like Blue too!
并且您可能必須洗掉不需要的元素。
但是,如果需要從外部腳本的第一個答案中獲取輸出以決定將什么作為下一個答案發送,那么就會出現問題。
它需要subprocess.Popen()運行并同時發送輸入和讀取輸出。但還有其他問題。如果與外部腳本發送線路\n,那么你可以閱讀它readline(),但如果它不發送\n,然后readline()等待\n,它會阻止Python代碼。如果它發送一行,則相同,但您將嘗試讀取 2 行。第二個readline()會阻止它。所以你必須知道它發送了多少行。
如果你使用,read()那么它會等待資料結束,它也會阻塞 Python。如果您使用read(100)并且輸出將有 100 個位元組(或更多),那么它將讀取 100 個位元組(其余將等待下一個read()- 但如果它有 99 個位元組,read(100)則將阻止 Python。
您必須知道要讀取多少位元組,或者您必須知道它可能發送什么文本,然后您可以read(1)將其添加到緩沖區,并檢查緩沖區是否具有您期望的字串。而這種方法使用expect和pyexpect。
第一個例子 readline()
我用example.sh與\n在printf
printf "Hello, who is running this program? \n"
read -r USERNAME
echo Hi $USERNAME!
printf "What is your favorite color? \n"
read -r COLOR
echo I like $COLOR too!
因為example.sh發送\n所以我洗掉\n
import subprocess
cmd = ['sh', 'example.sh']
p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
print('1 >>>', p.stdout.readline().decode().rstrip(), '<<<')
p.stdin.write("Larry!\n".encode())
p.stdin.flush()
print('2 >>>', p.stdout.readline().decode().rstrip(), '<<<')
print('1 >>>', p.stdout.readline().decode().rstrip(), '<<<')
p.stdin.write("Blue!\n".encode())
p.stdin.flush()
print('2 >>>', p.stdout.readline().decode().rstrip(), '<<<')
結果:
1 >>> Hello, who is running this program? <<<
2 >>> Hi Larry!! <<<
1 >>> What is your favorite color? <<<
2 >>> I like Blue! too! <<<
編輯:
示例中 pexpect
類似于第一個版本 - 我發送所有答案并獲得所有輸出
import pexpect
p = pexpect.spawn('sh script.sh')
p.sendline('Larry')
p.sendline('Blue')
p.expect(pexpect.EOF) # wait for output
print(p.before.decode())
類似于第二個例子。Pexpect 將輸入作為輸出發送,因此它需要額外的 `readline()
import pexpect
p = pexpect.spawn('sh script.sh')
# ---
p.readline()
print('output 1 >>>', p.before.decode(), '<<<')
p.sendline('Larry')
p.readline()
print('input >>>', p.before.decode(), '<<<')
p.readline()
print('output 2 >>>', p.before.decode(), '<<<')
# ---
p.readline()
print('output 1 >>>', p.before.decode(), '<<<')
p.sendline('Blue')
p.readline()
print('input >>>', p.before.decode(), '<<<')
p.readline()
print('output 2 >>>', p.before.decode(), '<<<')
p.expect(pexpect.EOF) # get rest to the end
print('end:', p.before.decode())
而不是readline()它可以使用expect(regex)或expect_exact(text)
import pexpect
p = pexpect.spawn('sh script.sh')
# ---
p.expect_exact('\r\n')
print('output 1 >>>', p.before.decode(), '<<<')
p.sendline('Larry')
p.expect_exact('\r\n')
print('input >>>', p.before.decode(), '<<<')
p.expect_exact('\r\n')
print('output 2 >>>', p.before.decode(), '<<<')
# ---
p.expect_exact('\r\n')
print('output 1 >>>', p.before.decode(), '<<<')
p.sendline('Blue')
p.expect_exact('\r\n')
print('input >>>', p.before.decode(), '<<<')
p.expect_exact('\r\n')
print('output 2 >>>', p.before.decode(), '<<<')
p.expect(pexpect.EOF) # get rest to the end
print('end:', p.before.decode())
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/364451.html
