ดำเนินการรวมคำสั่ง Linux หลายคำสั่งในหนึ่งบรรทัด


329

ฉันกำลังพยายามรวมคำสั่ง linux หลายคำสั่งในหนึ่งบรรทัดเพื่อดำเนินการปรับใช้ ตัวอย่างเช่น

cd /my_folder
rm *.jar
svn co path to repo
mvn compile package install

คำตอบ:


717

หากคุณต้องการดำเนินการแต่ละคำสั่งหากคำสั่งก่อนหน้านี้ประสบความสำเร็จให้รวมคำสั่งเหล่านั้นโดยใช้&&โอเปอเรเตอร์:

cd /my_folder && rm *.jar && svn co path to repo && mvn compile package install

หากคำสั่งใดคำสั่งหนึ่งล้มเหลวคำสั่งอื่นทั้งหมดที่ตามมาจะไม่ถูกดำเนินการ

หากคุณต้องการดำเนินการคำสั่งทั้งหมดโดยไม่คำนึงว่าคำสั่งก่อนหน้านี้ล้มเหลวหรือไม่ให้คั่นด้วยเครื่องหมายอัฒภาค:

cd /my_folder; rm *.jar; svn co path to repo; mvn compile package install

ในกรณีของคุณฉันคิดว่าคุณต้องการกรณีแรกที่การดำเนินการของคำสั่งถัดไปขึ้นอยู่กับความสำเร็จของคดีก่อนหน้า

คุณสามารถใส่คำสั่งทั้งหมดในสคริปต์และดำเนินการแทน:

#! /bin/sh
cd /my_folder \
&& rm *.jar \
&& svn co path to repo \
&& mvn compile package install

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

บันทึกไฟล์นั้นลงในไฟล์myscriptและทำให้สามารถเรียกใช้งานได้:

chmod +x myscript

ตอนนี้คุณสามารถรันสคริปต์นั้นเหมือนกับโปรแกรมอื่น ๆ ในเครื่อง แต่ถ้าคุณไม่ได้วางไว้ในไดเรกทอรีที่ระบุไว้ในPATHตัวแปรสภาพแวดล้อมของคุณ(ตัวอย่างเช่น/usr/local/binหรือใน Linux บางตัว~/bin) คุณจะต้องระบุพา ธ ไปยังสคริปต์นั้น หากอยู่ในไดเรกทอรีปัจจุบันคุณจะดำเนินการกับ:

./myscript

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

#! /bin/sh
cd /my_folder
rm *.jar
svn co path to repo
mvn compile package install

38
สำหรับผู้อ่านในอนาคต: คุณสามารถใช้||แทนเซมิโคลอนหรือ&&ถ้าคุณต้องการให้คำสั่งถัดไปถูกเรียกใช้หากคำสั่งสุดท้ายล้มเหลว เช่นเดียวกับในการลองสิ่งนี้และหากล้มเหลวให้ลองทำเช่นนั้น
DeVadder

3
อืมอัฒภาคไม่ได้ผลเสมอไป เช่นls >/dev/null & ; echo $!ทำให้เกิดข้อผิดพลาด
สวัสดีแองเจิล

1
และถ้าฉันต้องการเรียกใช้คำสั่งแรกในพื้นหลังและอื่น ๆ ในเบื้องหน้า .. ฉันกำลังลองสิ่งนี้tail -f my.log & && ./myscriptซึ่งไม่ทำงาน .. โปรดแนะนำ
OverrockSTAR

4
@Pareshkumar ด้วย bash คุณสามารถทำได้: { tail -f my.log & } && ./myscriptอย่างไรก็ตามโปรดทราบว่านั่น&&เป็นสิ่งที่ไร้ประโยชน์ที่นี่เนื่องจากงานแรกทำงานในพื้นหลังและงานที่สองไม่สามารถทราบผลเนื่องจากงานทั้งสองจะเริ่มในเวลาเดียวกัน ดังนั้นคุณอาจเขียน:{ tail -f my.log & }; ./myscript
Nikos C.

ถ้าฉันต้องการการsudoอนุญาตให้เรียกใช้คำสั่งอย่างใดอย่างหนึ่ง ฉันควรจะใส่sudoคำสั่งทั้งหมดหรือแค่คำสั่งที่ต้องการหรือไม่ ฉันจะส่งรหัสผ่านไปยังคำสั่งนั้นเพื่อให้ดำเนินการอย่างถูกต้องได้อย่างไร
Drubio

46

ฉันพบว่าใช้ เพื่อแยกคำสั่งทำงานในเบื้องหน้าเท่านั้น เช่น :

cmd1; cmd2; cmd3 & - จะดำเนินการcmd3ในพื้นหลังเท่านั้นในขณะที่ cmd1 && cmd2 && cmd3 &- จะดำเนินการสายโซ่ทั้งหมดในพื้นหลังหากไม่มีข้อผิดพลาด

เพื่อรองรับการประมวลผลแบบไม่มีเงื่อนไขโดยใช้วงเล็บแก้ปัญหานี้:

(cmd1; cmd2; cmd3) & - จะดำเนินการเชนคำสั่งในพื้นหลังแม้ว่าขั้นตอนใด ๆ จะล้มเหลว


1
แอมเปอร์แซนด์ต่อท้าย (&) ในตัวอย่างของคุณตั้งใจหรือไม่ ถ้าเป็นเช่นนั้นมีไว้เพื่ออะไร?
Technophile

5
@Technophile มันจะเรียกใช้คำสั่งพื้นหลัง
โอ๊ก Chantosa

1
หนึ่งคำตอบที่ง่ายสั้นและตรงคุณควรใช้เว็บไซต์ StackExchange บ่อยครั้งที่ดีน ขอบคุณสำหรับข้อมูลของคุณ
CPHPython

10

คุณสามารถแยกคำสั่งโดยใช้เซมิโคลอน:

cd /my_folder;rm *.jar;svn co path to repo;mvn compile package install

นั่นคือสิ่งที่คุณหมายถึงอะไร


3

หากต้องการเรียกใช้ทั้งหมดในครั้งเดียวคุณสามารถใช้ปุ่มไปป์ไลน์ "|" ชอบมาก:

$ cd /my_folder | rm *.jar | svn co path to repo | mvn compile package install

1
ไพพ์ไลน์กำลังถูกใช้เพื่อให้เอาต์พุตของคำสั่งของคุณกับคำสั่งถัดไปเป็นอินพุต ตัวอย่างเช่น: X | Y -> X คำสั่งเอาต์พุตจะทำงานเป็นอินพุตสำหรับคำสั่ง Y
Arpan Saini

2

หากคุณต้องการรันคำสั่งทั้งหมดไม่ว่าคำสั่งก่อนหน้าจะทำงานหรือไม่คุณสามารถใช้เครื่องหมายอัฒภาค (;) เพื่อแยกคำสั่ง

cd /my_folder; rm *.jar; svn co path to repo; mvn compile package install

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

cd /my_folder && rm *.jar && svn co path to repo && mvn compile package install

ในกรณีของคุณการดำเนินการของคำสั่งที่ต่อเนื่องกันดูเหมือนจะขึ้นอยู่กับคำสั่งก่อนหน้าดังนั้นให้ใช้ตัวอย่างที่สองเช่นใช้ && เพื่อเข้าร่วมคำสั่ง


1
cd /my_folder && rm *.jar && svn co path to repo && mvn compile package install

มันไม่เหมือนกับสคริปต์ OP โปรดอธิบาย: หากคำสั่ง aa ล้มเหลวสคริปต์จะหยุด
Gilles Quenot

4
นอกจากนี้คุณสามารถใช้cmd1 || cmd2ตัวคั่นได้หากคุณจำเป็นต้องcmd2ดำเนินการเฉพาะในกรณีที่cmd1ส่งคืนสถานะที่ไม่เป็นศูนย์ให้กับเชลล์และคุณอาจใช้cmd1 ; cmd2หากคุณต้องการรันทั้งสองคำสั่งโดยไม่คำนึงถึงสถานะการส่งคืน
Victor Sorokin

@ sputnick มันควรจะเป็นฉันเพิ่งวางมันและตัดแบ่งคำสั่งด้วย &&
Mark Stevens

3
@ MarkStevens มันเป็นการใช้งานที่ดีกว่า แต่มันจะไม่ได้ผลเหมือนกันกับว่าถ้าคำสั่งนั้นถูกเรียงลำดับตามลำดับฉันคิดว่านั่นเป็นสิ่งที่ sputnick หมายถึง
andrux

1

แอมเปอร์แซนด์เพียงอันเดียวคืออะไร เช้านี้ฉันได้เปิดตัวในแผง XFCE (ใน Manjaro + XFCE) เพื่อเปิดตัวจัดการรหัสผ่าน 2 ตัวพร้อมกัน:

sh -c "keepassx && password-gorilla"
or
sh -c "keepassx; password-gorilla"

แต่มันไม่ทำงานตามที่ฉันต้องการ IE แอปแรกจะเริ่มทำงาน แต่แอปที่สองจะเริ่มก็ต่อเมื่อปิดก่อนหน้านี้

อย่างไรก็ตามฉันพบว่า (มีเครื่องหมายเดียวเท่านั้น):

sh -c "keepassx & password-gorilla"

และมันทำงานได้ตามที่ฉันต้องการตอนนี้ ...


1
เครื่องหมายแอมเปอร์แซนด์ทำหน้าที่เป็นตัวยกเลิกคำสั่งคล้ายกับ;ยกเว้นสิ่งนี้ทำให้คอมมานด์อยู่ข้างหลังมันคือเชลล์จะไม่เห็นเอาต์พุต
Sergiy Kolodyazhnyy

-1

คุณสามารถใช้เป็นรหัสต่อไปนี้

cd /my_folder && \
rm *.jar && \
svn co path to repo && \
mvn compile package install

มันได้ผล...


-1

ฉันพบคำตอบมากมายสำหรับคำถามประเภทนี้ที่ทำให้เข้าใจผิด

แก้ไขจากโพสต์นี้: https://www.webmasterworld.com/linux/3613813.htm

รหัสต่อไปนี้จะสร้างหน้าต่างทุบตีและทำงานเหมือนกับหน้าต่างทุบตี หวังว่านี่จะช่วยได้ มีคำตอบที่ผิด / ไม่ได้ทำงานมากเกินไป ...

            Process proc;
            try {
                //create a bash window
                proc = Runtime.getRuntime().exec("/bin/bash");
                if (proc != null) {
                       BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
                       PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())), true);
                       BufferedReader err = new BufferedReader(new InputStreamReader(
                       proc.getErrorStream()));
                       //input into the bash window
                       out.println("cd /my_folder");
                       out.println("rm *.jar");
                       out.println("svn co path to repo");
                       out.println("mvn compile package install");
                       out.println("exit");
                       String line;
                        System.out.println("----printing output-----");
                          while ((line = in.readLine()) != null) {
                             System.out.println(line);
                          }
                          while((line = err.readLine()) != null) {
                             //read errors
                          }
                          proc.waitFor();
                          in.close();
                          out.close();
                          err.close();
                          proc.destroy();
                }

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.