สร้าง 'ไฟล์เสมือน' จากคำสั่ง bash หรือไม่


36

ฉันสงสัยว่ามีวิธีการสร้าง 'ไฟล์เสมือน' จาก bash output หรือไม่

ตัวอย่าง: สมมติว่าฉันต้องการส่งออกอีเมลmysqldumpเป็นไฟล์แนบไปยังที่อยู่อีเมลภายนอก ฉันสามารถใช้ Mutt ในการทำเช่นนั้นได้ ตัวเลือกที่ฉันจำเป็นต้องใช้งานmutt -a <name of the file I want to attach>ฉันรู้ว่าฉันสามารถใช้ไฟล์ชั่วคราว:

mysqldump mysqldumpoptions > /tmp/tempfile && mutt -a /tmp/tempfile admin@example.org

แต่ฉันอยากจะเปลี่ยนเส้นทางmysqldumpผลลัพธ์โดยตรงไปยัง Mutt แทน -aตัวเลือกของ Mutt ยอมรับเฉพาะไฟล์และไม่ใช่สตรีม แต่อาจมีวิธีส่งไฟล์ descriptor เสมือนหรืออะไรบางอย่างตามบรรทัดเหล่านั้น สิ่งที่ต้องการ:

mutt -a $(mysqldump mysqldumpoptions) admin@example.org

มันเป็นไปได้? ถ้าไม่ทำไม

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


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

คำตอบ:


53

นี่เป็นวิธีที่สะอาดที่สุดในการทำสิ่งที่คุณต้องการ:

mutt admin@example.org -a <(mysqldump mysqldumpoptions)

<()ผู้ประกอบการเป็นสิ่งที่คุณกำลังขอ; มันสร้าง FIFO (หรือ / dev / fd) และส้อมกระบวนการและเชื่อมต่อ stdout กับ FIFO >()ทำเช่นเดียวกันยกเว้นเชื่อมต่อ stdin กับ FIFO แทน กล่าวอีกนัยหนึ่งมันทำทุกสิ่งที่ mknod ให้คุณอยู่เบื้องหลัง หรือในระบบปฏิบัติการที่ทันสมัยทำในวิธีที่ดียิ่งขึ้น

ยกเว้นแน่นอนว่ามันใช้งานไม่ได้กับ mutt มันบอกว่า:

/dev/fd/63: unable to attach file.

ฉันสงสัยว่าปัญหาคือว่า mutt พยายามค้นหาไฟล์ซึ่งคุณไม่สามารถทำได้ในทุกประเภท การค้นหาอาจเป็นสิ่งที่ต้องการสแกนไฟล์เพื่อค้นหาว่า MIME เป็นแบบใดและการเข้ารหัสใดที่ใช้งานได้ (เช่นไม่ว่าจะเป็นไฟล์ 7 บิตหรือ 8 บิต) จากนั้นค้นหาจุดเริ่มต้นของไฟล์เพื่อเข้ารหัสเป็นข้อความจริง .

หากสิ่งที่คุณต้องการส่งเป็นข้อความธรรมดาคุณสามารถทำสิ่งนี้ได้ตลอดเวลาเพื่อให้เป็นเนื้อหาหลักของอีเมลแทน (ไม่เหมาะ แต่มันใช้งานได้จริง):

mysqldump mysqldumpoptions | mutt -s "Here's that mysqldump" admin@example.org

2
! น่ากลัว ฉันเห็นการเปลี่ยนเส้นทางดังกล่าวเป็นครั้งแรก
Saurabh Barjatiya

ขอบคุณสำหรับคำอธิบายที่ดี! ฉันไม่เคยเห็นสิ่งนี้มาก่อนในบทเรียนใด ๆ เกี่ยวกับการเปลี่ยนเส้นทาง I / O
Christian Mann

4

ฉันคิดว่าสิ่งที่คุณกำลังมองหาคือ Fifo ใช้ mknod

mknod /tmp/foo p

echo hello > /tmp/foo &

cat /tmp/foo

หมายเหตุกระบวนการเขียนจะบล็อกหากไม่มีกระบวนการอ่าน

เช่น

mknod /tmp/foo p

mysqldump mysqldumpoptions > /tmp/foo &

mutt -a /tmp/foo

1

จำเป็นต้องมีไฟล์แนบหรือไม่ ถ้ามันสามารถปรากฏเป็นเนื้อหาของข้อความ (7-bit clean ascii, ไม่มี '.' ในบรรทัดด้วยตัวเอง ฯลฯ ) จากนั้นสิ่งเช่นนี้จะทำงาน:

mysqldump mysqldumpoptions | mutt -s "การถ่ายโอนข้อมูล mysql วันนี้" admin@example.org


1

คุณอาจจะสามารถใช้ชื่อไฟล์/dev/stdinด้วย mutt ซึ่งจะอ่านจาก stdin

mysqldump mysqldumpoptions | mutt -a /dev/stdin admin@example.org

หืมมฉันเพิ่งลองและบ่นว่า:

/dev/stdin isn't a regular file.
/dev/stdin: unable to attach file.

โอ้ดี ฉันคิดว่าสิ่งนี้ตอบคำถามของคุณด้วย-aตัวเลือกว่าคาดว่าไฟล์ปกติซึ่งหมายถึงไม่ใช่อุปกรณ์หรือไปป์


1

FIFO น่าจะเป็นวิธีที่ดีที่สุด อย่างไรก็ตามคุณสามารถใช้mkfifo /path/to/fifoแทน


0

ฉันอาจจะหายไปบางสิ่งบางอย่างที่นี่ แต่ทำไมใช้ mutt เมื่อฟังดูคล้ายกับงานสำหรับ / usr / sbin / sendmail (หรือที่ใดก็ตามที่มันอยู่ใน distro ของคุณ)?

mysqldump mysqldumpoptions | sendmail admin@example.org

MTA ของยูนิกซ์ส่วนใหญ่จะให้คำสั่ง / usr / sbin / sendmail และพวกเขาทั้งหมดเข้าใจตัวเลือกเดียวกันมากขึ้นหรือน้อยลงและทำงานในลักษณะเดียวกันมากกว่าหรือน้อยกว่า ในเกือบทุกกรณีคุณไม่จำเป็นต้องสนใจว่า MTA / การใช้งาน sendmail แบบใดที่คุณใช้อยู่

มีทางเลือกอื่น ๆ อีกมากมายรวมถึง mail / mailx


1
แล้วมันไม่ได้เป็นสิ่งที่แนบมาซึ่งดูเหมือนว่าน่าจะเป็นเรื่องยากที่จะใช้สำหรับผู้รับ
Freiheit

1
ในกรณีนั้นทางออกที่ดีกว่าคือการใช้เครื่องมือเช่น metamail (1) หรือ mime-construct (1p) หรือเขียนของคุณเองโดยใช้สิ่งที่ต้องการโมดูล Perl MIME :: Lite (ส่วนตัวที่ชื่นชอบเพราะทำให้ง่ายต่อการทำ สิ่งที่เกี่ยวข้องกับละครใบ้ทั่วไปมากที่สุด)
cas

0

ตัวเลือก Mutt -a ใช้ประเภท MIME ที่กำหนดไว้ที่ /etc/mime.types โดยเฉพาะ ไม่มีประเภทไฟล์เสมือนที่คุณคิดว่าจริง ๆ แล้วเป็นประเภท mime ที่ถูกต้องที่ลงทะเบียนดังนั้นฉันไม่คิดว่าไฟล์แนบ mutt จะใช้งานได้ เพียงเพื่อพิสูจน์แนวคิดคุณสามารถลองติดตั้งแพ็คเกจสนับสนุน mime (ซึ่งมีไบนารีการเข้าถึงไฟล์ mime เช่นดูแก้ไข ฯลฯ ) และเรียกใช้ดูกับไฟล์เสมือน (พูดไปป์) คุณจะเห็นว่ามันไม่ ไม่รู้จัก ปัญหาพื้นฐานคือโดยปกติแล้วไฟล์เสมือนจะเก็บเนื้อหาข้อมูลในหน่วยความจำไม่ใช่ในดิสก์วัตถุไฟล์เป็นเพียงตัวชี้ คุณสามารถลองตัดไฟล์เสมือนด้วย tar / gz และทำให้ mutt มีความสุข แต่ฉันสงสัยว่าคุณจะได้รับประโยชน์อะไรจากสิ่งอื่น ๆ ... :)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.