ส่งข้อความไปยังโปรแกรมโดยหวังว่าไฟล์


30

เกี่ยวข้องกับคำถามที่ฉันถามใน Stack Overflow: การส่งรหัสหลายบรรทัดไปที่ wsadmin.sh หรือไม่ .

ฉันมีสายป้อนข้อมูลสองสามบรรทัดที่ฉันต้องป้อนลงในคำสั่ง อย่างไรก็ตามคำสั่งยอมรับเฉพาะไฟล์ที่เต็มไปด้วยอินพุต

มีวิธีใดบ้างที่ฉันสามารถจัดเก็บบรรทัดในไฟล์ชั่วคราวหรือไพพ์ซึ่งไม่เคยเขียนลงดิสก์จริงแล้วป้อนฟีดลงในโปรแกรมโดยตรง

ฉันจะไปเกี่ยวกับการรับไปป์, ป้อนข้อมูลเข้าไป, ผ่านไปป์นั้นไปยังคำสั่ง, แล้วกำจัดไพพ์?


2
คุณสามารถเพิ่มตัวอย่างของคำสั่งที่คุณใช้และควรจะเรียกใช้อย่างไร
พัฒนา

2
หมายความว่าโปรแกรมไม่ยอมรับ stdin หรือไม่
Léo Lam

ฉันเห็นด้วยกับผู้แสดงความคิดเห็นทั้งสองคนข้างต้น เป็นไปไม่ได้ที่จะแนะนำอะไรที่อาจใช้งานได้โดยที่ไม่ทราบรายละเอียดของโปรแกรม
Larssend

คำตอบ:


27

อีกวิธีคือการใช้การทดแทนกระบวนการใน Bash หากระบบของคุณมีชื่อไปป์คุณสามารถใช้คุณสมบัตินี้ได้

มันถูกใช้อย่างนี้:

program_expecting_a_file <(list)

โดยที่listเป็นลำดับของคำสั่งเชลล์ (จริง ๆ แล้วท่อ; รายละเอียดทั้งหมดอยู่ที่นี่ ) listจะถูกดำเนินการและเอาท์พุทของมันจะถูกเชื่อมต่อกับท่อ ชื่อของไพพ์นั้นจะถูกส่งผ่านไปยังโปรแกรมของคุณ

หมายเหตุ:ช่องว่างที่ไม่ได้รับอนุญาตระหว่างและ<(

(การทดแทนอื่นสามารถใช้>(list)งานได้ตามที่คุณคาดหวัง)

ในกรณีเฉพาะของคุณคุณสามารถใช้

program_expecting_a_file <(echo "$your_strings")

แม้ว่าคุณอาจจะพบว่าวิธีการแก้ปัญหาของ @ meuh นั้นสวยงามกว่า

ปรับปรุง:ตัวอย่างการใช้งานที่ดีมากที่จะพบในช่วงที่สินค้าทุกประเภททุบตี Scripting คู่มือ


อีกสองคนไม่ได้ทำงานแม้แต่ในกรณีที่น่ารำคาญที่สุด คุณผ่านการทดสอบที่ฉันโยนไปแล้ว ตอนนี้ฉันได้เพิ่มคะแนนของคุณแล้ว ฉันจะกลับมาและทำเครื่องหมายว่าเป็นที่ยอมรับถ้าทำทุกอย่างที่ฉันต้องการ
ArtOfWarfare

ของคุณทำงานอย่างสมบูรณ์ หากคุณต้องการคุณสามารถเพิ่มคำถามที่เกี่ยวข้องใน StackOverflow และฉันสามารถยอมรับได้ที่นั่นเช่นกัน stackoverflow.com/questions/31374202/…
ArtOfWarfare

สวัสดี @ArtOfWarfare ดีใจที่ได้รับความช่วยเหลือ มีความคิดเห็นอยู่ที่นั่นแล้วด้วยวิธีการแก้ปัญหาที่เสนอเดียวกันดังนั้นมันจะไม่ถูกต้องสำหรับฉันที่จะโพสต์คำตอบที่นั่น
Edward

คุณโพสต์โซลูชั่นของคุณก่อนที่เขาจะทำ อย่างไรก็ตามฉันขอให้เขาเปลี่ยนความคิดเห็นของเขาเป็นคำตอบเพื่อให้ฉันยอมรับได้ หากคุณไม่ตอบคำถามภายใน ~ 24 ชั่วโมงฉันก็แค่โพสต์คำตอบเองเพื่อที่ฉันจะยอมรับได้ (ฉันไม่ชอบที่จะทิ้งคำถามไว้เหมือนไม่ได้ตอบเมื่อฉันพบว่าคำตอบคืออะไร มารยาทที่ไม่ดีสำหรับผู้อ่านในอนาคต / ผู้ตอบคำถามที่เป็นไปได้)
ArtOfWarfare

สวัสดี @ArtOfWarfare ฉันสบายดีกับสิ่งที่คุณเสนอ!
Edward

15

คุณสามารถใช้ทุบตีนี่ doc ตัวอย่างเช่น,

$ cat -n <<<'a
> b'
 1  a
 2  b

<<<"path is $PATH"ถ้าคุณมีบางสิ่งบางอย่างในตัวแปรทุบตีคุณยังสามารถสอดแทรกมันเช่น


หากคำสั่งของคุณยืนยันชื่อไฟล์คุณสามารถให้มัน/dev/stdinได้ เช่น:

$ sed -f /dev/stdin <<<'s/a/b/'

ผลิตผลลัพธ์: s/b/b/.


ไม่ชัดเจนจากคำถามว่าคำสั่งรับอินพุตstdinหรือไม่และถ้าไม่คำสั่งจะไม่ทำงาน ฉันหวังว่า OP ชัดเจน
David Z

1
:( - สิ่งนี้ดูมีแนวโน้มดีมาก แต่เมื่อฉันลองฉันได้รับข้อความแสดงข้อผิดพลาด"-f" option must be followed by a file name.
ArtOfWarfare

เอกสารที่นี่มีไว้สำหรับ stdin หากคำสั่งของคุณอย่างแน่นอนความต้องการและชื่อไฟล์แล้วให้ชื่อไฟล์-f /dev/stdinดูการแก้ไขของฉัน
meuh

ฉันคิดว่าหลังจากการแก้ไขมันเป็นตัวเลือกที่เหมาะสม!
Edward

1
+1 สำหรับ/dev/stdinคำแนะนำ โปรแกรมที่ฉันพยายามเรียกใช้ยอมรับชื่อไฟล์เท่านั้นดังนั้นฉันจึงรวม/dev/stdinกับ heredoc
Huw Walters

7

คุณอาจจะสามารถใช้ชื่อไฟล์พิเศษ - (ลบ) ซึ่งหมายถึงstdinทั้งนี้ขึ้นอยู่กับสิ่งที่อยู่ในสคริปต์

$ mycmd -
Line 1
Line 2
^D

วิธีการซึ่งอาจทำงานสำหรับคุณก็คือการเปิดไฟล์/dev/fd/0อีกครั้งซึ่งย่อมาจากstdin

ตัวเลือกที่สามอาจเป็นการสร้างFIFO (เข้าก่อนออกก่อน) นั่นเป็นเหมือนไฟล์ แต่มันมีทั้งสองด้าน - คุณเขียนไปที่ปลายด้านหนึ่งและอ่านจากอีกด้านหนึ่ง

-- Process 1 --                  -- Process 2 --
$ mkfifo foo
$ cat foo
<waits>                          $ echo hello > foo
hello                            $
$ rm foo

3
อาจเป็นเรื่องที่น่าสังเกตว่าโปรแกรมจะต้องเขียนขึ้นเพื่อตีความ-วิธีนี้ - ไม่ใช่คุณสมบัติของเชลล์หรือระบบปฏิบัติการ แม้ว่ายูทิลิตี้ Linux มาตรฐานส่วนใหญ่จะปฏิบัติตามอนุสัญญานี้เท่าที่ฉันรู้
David Z

1
Nope สิ่งนี้ใช้ไม่ได้กับโปรแกรม มีโหมดการโต้ตอบเป็น expectแต่ผมต้องการที่จะผ่านคำสั่งในการดำเนินการที่จะใช้โปรแกรมนี้จากโปรแกรมอื่นและผมไม่ต้องการที่จะได้รับในกระต่ายที่เป็นหลุม
ArtOfWarfare

@ArtOfWarfare ฉันเพิ่งเพิ่มตัวเลือกที่สามที่อาจใช้งานได้
Majenko

คำตอบที่ดี! ตัวเลือกที่สองและสามนั้นเป็นเหมือน<()โซลูชัน แต่ชัดเจนกว่า - ซึ่งอาจมีประโยชน์มาก!
Edward

4

มีตัวเลือกอื่นคล้ายกับmycmd -โซลูชัน แต่สำหรับโปรแกรมที่ไม่ได้จัดการ-โดยเฉพาะ:

$ mycmd /dev/stdin
Line 1
Line 2
^D

/dev/stdin ดูเหมือนว่าจะเกี่ยวกับระบบปฏิบัติการและทำงานได้ดีสำหรับฉันบน Debian GNU / Linux แต่ฉันไม่แน่ใจว่าจะใช้ที่อื่นได้อีกเช่นกัน


1
ดูเหมือนว่ามันจะใช้งานได้ แต่มันคือ^Dอะไร
ArtOfWarfare

^Dเป็นสัญกรณ์ทั่วไปสำหรับการกด Ctrl-D ^ D มีความหมายของ "จุดสิ้นสุดของอินพุตสตรีม" ที่นี่ มันอาจจะเห็นบ่อยขึ้นใน^Cหรือ^Zที่ยืนสำหรับการกด Ctrl-C ตามลำดับสำหรับการกด Ctrl-Z
Axel Beckert

1
ดูเหมือนว่าจะใช้งานได้ แต่ฉันจะใส่ของเข้าไปในโปรแกรม/dev/stdinแล้วปิดได้อย่างไร
ArtOfWarfare

1
cat content | mycmd /dev/stdinบางสิ่งบางอย่างท่อเพียงแค่เข้าไปในคำสั่งนั้นและมันควรจะทำงานคือ ลองจินตนาการคำสั่งที่แตกต่างจากcatที่นี่
Axel Beckert
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.