การใช้คำสั่ง exec ที่เป็นไปได้คืออะไร?


10

ฉันกำลังเรียนรู้execคำสั่ง ฉันรู้ว่าexecคำสั่งแทนที่กระบวนการที่เริ่มต้นแล้ว ดังนั้นจึงเป็นไปไม่ได้ที่จะกลับไปสู่กระบวนการซึ่งถูกแทนที่ด้วยexecคำสั่ง

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

แต่สิ่งอื่น ๆ ที่ใช้สำหรับการมีสิ่งที่ต้องการexecเป็นคำสั่งคืออะไร?



1
จากบทความวิกิพีเดีย: "สคริปต์แรปเปอร์มักใช้คำสั่งนี้เพื่อเรียกใช้โปรแกรม (ทั้งโดยตรงหรือผ่านเครื่องแปลภาษาหรือเครื่องเสมือน) หลังจากตั้งค่าตัวแปรสภาพแวดล้อมหรือการกำหนดค่าอื่น ๆ "
knb


2
โดยส่วนตัวแล้วฉันพบว่าexec ssh server-that-does-byobu-on-login.example.comเป็นที่ชื่นชอบมากในการที่ ^ A ^ D ปิดสถานีทั้งหมด (โดยทั่วไปexec byobu(หรือexec screen, exec tmux)
Williham Totland

คำตอบ:


9

ในสคริปต์ตัวตัด

exec ส่วนใหญ่จะใช้ในสคริปต์แรปเปอร์

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

นี่คือตัวอย่างการใช้งานจริงของมัน มันเป็นmate-terminal.wrapperสคริปต์ที่มาพร้อมกับ mate-terminal มันเริ่มmate-terminalด้วยอาร์กิวเมนต์พิเศษบางอย่างโดยการตรวจสอบสภาพแวดล้อมของผู้ใช้

#!/usr/bin/perl -w

my $login=0;

while ($opt = shift(@ARGV))
{
    if ($opt eq '-display')
    {
        $ENV{'DISPLAY'} = shift(@ARGV);
    }
    elsif ($opt eq '-name')
    {
        $arg = shift(@ARGV);
        push(@args, "--window-with-profile=$arg");
    }
    elsif ($opt eq '-n')
    {
        # Accept but ignore
        print STDERR "$0: to set an icon, please use -name <profile> and set a profile icon\n"
    }
    elsif ($opt eq '-T' || $opt eq '-title')
    {
        push(@args, '-t', shift(@ARGV));
    }
    elsif ($opt eq '-ls')
    {
        $login = 1;
    }
    elsif ($opt eq '+ls')
    {
        $login = 0;
    }
    elsif ($opt eq '-geometry')
    {
        $arg = shift(@ARGV);
        push(@args, "--geometry=$arg");
    }
    elsif ($opt eq '-fn')
    {
        $arg = shift(@ARGV);
        push(@args, "--font=$arg");
    }
    elsif ($opt eq '-fg')
    {
        $arg = shift(@ARGV);
        push(@args, "--foreground=$arg");
    }
    elsif ($opt eq '-bg')
    {
        $arg = shift(@ARGV);
        push(@args, "--background=$arg");
    }
    elsif ($opt eq '-tn')
    {
       $arg = shift(@ARGV);
       push(@args, "--termname=$arg");
    }
    elsif ($opt eq '-e')
    {
        $arg = shift(@ARGV);
        if (@ARGV)
        {
            push(@args, '-x', $arg, @ARGV);
            last;
        }
        else
        {
            push(@args, '-e', $arg);
        }
        last;
    }
    elsif ($opt eq '-h' || $opt eq '--help')
    {
        push(@args, '--help');
    }
}
if ($login == 1)
{
    @args = ('--login', @args);
}
exec('mate-terminal',@args);

จุดสังเกตที่นี่คือมีexecสายซึ่งแทนที่สคริปต์นี้ในหน่วยความจำ

นี่คือคำถามที่คล้ายกันตอบใน Unix & Linux StackExchange ไซต์ - https://unix.stackexchange.com/q/270929/19288

เพื่อเปลี่ยนเส้นทางอธิบายไฟล์

การใช้งานทั่วไปอีกอย่างหนึ่งexecคือการเปลี่ยนเส้นทางตัวอธิบายไฟล์ stdin, stdout, stderrสามารถเปลี่ยนเส้นทางไปยังไฟล์โดยใช้ exec

  1. การเปลี่ยนเส้นทางstdout- exec 1>fileจะทำให้เอาต์พุตมาตรฐานเป็นไฟล์ที่มีชื่อfileสำหรับการสิ้นสุดเซสชันเชลล์ปัจจุบัน สิ่งใดที่ส่งออกไปยังจอแสดงผลจะอยู่ในไฟล์

  2. การเปลี่ยนเส้นทางstdin- นอกจากนี้ยังสามารถใช้เพื่อเปลี่ยนเส้นทางstdinไปยังไฟล์ ตัวอย่างเช่นถ้าคุณต้องการที่จะเรียกใช้ไฟล์สคริปต์script.shคุณก็สามารถเปลี่ยนเส้นทางไปยังแฟ้มใช้stdinexec 0<script.sh


ตกลง. หลังจากนั้น 'mate-terminal' จะมี PID ที่ wrapper-script มีหรือไม่ และจะใช้หน่วยความจำที่ใช้กระดาษห่อสคริปต์? ดังนั้น wrapper-script จึงหายไป มิฉะนั้นสคริปต์ทั้งสองจะมีอยู่เป็นกระบวนการที่แยกต่างหากในระบบ
mizech

@mizech ใช่ พวกเขาใช้ PID เดียวกัน
Anwar

@mizech ดีใจที่รู้ว่ามันช่วย :)
Anwar

1
ตัวอย่างที่ยอดเยี่ยมที่ทำให้ชัดเจนจริงๆ
Zanna

คำตอบนี้เป็นเพียงบางส่วนและพลาดการใช้งานที่สำคัญอย่างใดอย่างหนึ่ง (โดยทั่วไป) ของexecมันคือการใช้ในการเปลี่ยนเส้นทางของตัวอธิบายไฟล์
heemayl

9

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

การใช้คำสั่ง exec ที่ใช้กันมากที่สุดสามวิธี:

1. การเปลี่ยนกระบวนการ

ตัวอย่างที่ 1: หากคุณเปิดbashเปลือกใหม่เป็น

$ bash 

ในpstreeนั้นดูเหมือนว่า

├─gnomeขั้ว
        ├─bash───bash───pstree

bashเชลล์ก่อนหน้านี้ยังอยู่ที่นั่นและคุณได้รับbashเชลล์ใหม่ โดยที่ถ้าคุณเปิด bash shell ใหม่เป็น

$ exec bash

การpstreeแสดง

├─gnomeขั้ว
        ├─bash───pstree

ที่นี่เก่าbashจะถูกแทนที่ด้วยใหม่ มีประโยชน์อย่างยิ่งที่จะออกจากการเข้าสู่ระบบหลายครั้งในหนึ่งคำสั่ง มีความปลอดภัยและกำจัดโอกาสในการออกจากเทอร์มินัลที่เปิดโดยไม่ได้ตั้งใจ ดูที่Exit จากทั้ง root และ user ด้วยคำสั่งเดียว

ตัวอย่าง -2:คุณสามารถเปิดไฟล์เป็น

$ exec vi filename.txt

เมื่อคุณออกจากระบบviไม่จำเป็นต้องปิดเครื่องแยกต่างหากเนื่องจากเชลล์ถูกแทนที่แล้ว ทันทีที่คุณปิด vi เทอร์มินัลก็จะปิดเช่นกัน

2. วิธีการเปลี่ยนเส้นทางของ file descriptors ภายในเชลล์สคริปต์

exec คำสั่งนอกจากนี้ยังสามารถนำมาใช้ในเชลล์สคริปต์เปิดแบบไดนามิกใกล้และคัดลอกอธิบายไฟล์ ที่อนุญาตให้ดำเนินการเปลี่ยนเส้นทางของ STDIN, STDERR, STDOUT และตัวอธิบายไฟล์อื่น ๆ ไปยังไฟล์ต่างๆภายในเชลล์สคริปต์แทนที่จะเป็นสตริงการเรียกใช้คำสั่ง หากคุณไม่ได้ระบุคำสั่งหรืออาร์กิวเมนต์คุณสามารถระบุสัญลักษณ์การเปลี่ยนเส้นทางและตัวอธิบายไฟล์เพื่อทำหน้าที่เหล่านี้

สมมติว่าคุณมีเชลล์สคริปต์ที่script.shคุณต้องการมีไฟล์บันทึกscript.logคุณสามารถใช้execเป็น

LOG=/path/to/script.log
exec 1>>$LOG
exec 2>&1

ซึ่งเทียบเท่ากับ

./script &>> /path/to/script.log
./script >>  /path/to/script.log 2>&1

3. การสร้างขั้นตอนของกระบวนการโดยใช้คำสั่ง exec

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

ในกรณีนี้คำสั่งสุดท้ายของแต่ละสเตจควรเป็นexecคำสั่งที่เรียกใช้สเตจถัดไป

ดูการใช้execคำสั่งในเชลล์สคริปต์สำหรับข้อมูลเพิ่มเติม

หมายเหตุ:บางส่วนของข้อมูลข้างต้นนำมาจากสิ่งนี้


1
เพียงคำตอบที่สมบูรณ์ (จนถึงตอนนี้)
heemayl

ทุกครั้งที่ฉันใช้ exec มีประสิทธิภาพ หากคุณเรียกใช้ daemon ด้วย exec คุณจะต้องมีกระบวนการที่ใช้งานเพียงกระบวนการเดียวแทนที่จะเป็นสองกระบวนการ ออกจากกระบวนการทุบตีรอบ ๆ ทำให้เปลือง RAM สักสองสาม MB รวมถึงสิ่งอื่น ๆ
gmatht

2

เท่าที่ฉันรู้ว่ามันยังใช้ในการเปลี่ยนเส้นทางอธิบายไฟล์ (ตัวอย่างเช่น STDOUT, STDERR, STDIN) ของ bash-script

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


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