ฉันจะรันแอปพลิเคชันด้วยอาร์กิวเมนต์บรรทัดคำสั่งใน Mac OS ได้อย่างไร


60

มีวิธีง่าย ๆ ในการต่อท้ายอาร์กิวเมนต์บรรทัดคำสั่งกับแอปพลิเคชันบน Mac หรือไม่? ตัวอย่างเช่นการเรียกใช้ Opera ในโหมดคีออสก์หรือใช้โปรไฟล์อื่นใน Firefox ฉันสามารถพิมพ์ได้

$ /Applications/Opera.app/Contents/MacOS/Opera -kioskmode
$ /Applications/Firefox.app/Contents/MacOS/firefox -P profilename -no-remote

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

ฉันได้พบว่าการเปิดใช้งานแอปพลิเคชันผ่าน bash หรือ Applescript ใช้งานได้บางส่วน:

# Bash
#!/bin/sh
/Applications/Firefox.app/Contents/MacOS/firefox -P default -no-remote

# Applescript    
do shell script "exec /Applications/Opera.app/Contents/MacOS/Opera -kioskmode"

ฉันสามารถทำให้ไฟล์ปฏิบัติการเหล่านี้และกำหนดไอคอนและทุกอย่างใช้งานได้ดียกเว้นว่าเมื่อฉันรันโปรแกรมหลอกเหล่านี้ไม่ว่าจะเป็นหน้าต่างเทอร์มินัลหรือไอคอน Applescript จะยังคงเปิดอยู่ตราบเท่าที่แอปพลิเคชันเปิดอยู่ สันนิษฐานได้ว่าการใช้คำสั่ง Applescript openจะหลีกเลี่ยงสิ่งนี้ แต่เนื่องจากฉันไม่ได้รันแอปพลิเคชันเนื่องจากเป็นแพคเกจ (เพียง/Applications/Firefox) จึงไม่ทำงาน

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

แก้ไข

ตามหน้า Mozilla Wikiจะเป็นการดีที่สุดที่จะใช้สคริปต์เพื่อเรียกใช้แอปพลิเคชั่นที่มีข้อโต้แย้ง การเพิ่ม a &ไปยังจุดสิ้นสุดของสคริปต์จะฆ่าหน้าต่างเทอร์มินัลแบบถาวร สิ่งเดียวที่น่ารำคาญในตอนนี้ก็คือมันจะเปิดหน้าต่างเทอร์มินัลที่ตายแล้วออกจากระบบ (ซึ่งดีกว่าแบบถาวร แต่ยัง ... )

#!/bin/sh
/Applications/Firefox.app/Contents/MacOS/firefox -P default -no-remote &

2
ฉันยังหวังว่าจะได้คำตอบที่ดีกว่านี้ ...
cregox

เมื่อคุณรันงานโดยที่&ยังคงเป็นของ Terminal คุณสามารถแก้ไขได้โดยเพิ่มบรรทัดdisown %/Applications/Firefox.app/Contents/MacOS/firefox หลังจากที่คุณเรียกใช้จากนั้นคุณสามารถปิด Terminal ได้อย่างปลอดภัยโดยใช้ AppleScript
ocodo

มองหาคำตอบของ Daniel - มันสมบูรณ์แบบที่สุดและสมบูรณ์แบบที่สุดสำหรับวันนี้ (OSX 10.6.2 +)
cregox

คำตอบ:


17

นี่คือทางออกที่ดีที่สุดของฉัน: สร้าง Applescript ด้วย:

do shell script "/Applications/Firefox.app/Contents/MacOS/firefox -P default -no-remote & killall Firefox.app"

และบันทึกเป็นแอปพลิเคชั่

คุณสามารถใส่แอพพลิเคชั่นอะไรก็ได้ที่มีส่วนที่อยู่ในส่วนแรก ส่วนหลังจาก&ต้องการฆ่าสิ่งที่คุณตั้งชื่อสคริปต์ + .app ของคุณ คุณจะเห็นแอปพลิเคชันสคริปต์กะพริบขึ้นที่แท่นวาง แต่จะหายไป

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


มันเกือบจะได้ผล ยังคงรอให้อินสแตนซ์ของ Firefox เสร็จสิ้นจนกว่ามันจะทำงาน killall ดังนั้นจึงเรียกโปรแกรมดีบั๊กเมื่อฉันปิด Firefox และแอปสคริปต์ยังไม่หายไป อืม ...
แอนดรู

แปลกแฮะ, แปลกนะ, มันแปลก ๆ นะ. คุณบันทึกเป็นแอพจากนั้นดับเบิลคลิกที่แอพหรือไม่ มันจะไม่ทำงานเมื่อเรียกใช้จาก Script Editor
MJeffryes

นอกจากนี้ฉันสังเกตเห็นว่าฉันใส่ newline ไว้ข้างหน้า & นำขึ้นบรรทัดใหม่ถ้าคุณมีมัน
MJeffryes

ไม่จำเป็นต้อง & ฆ่าทั้งหมดที่นี่ที่ Snow Leopard 10.6.x - แต่ก็ไม่สามารถหาวิธีที่จะทำให้แอปนี้ฆ่าตัวเองทันทีที่ดำเนินการ
cregox

1
@Pacerier ตรวจสอบวันที่ในคำตอบนี้
MJeffryes

28

เริ่มต้นใน OS X 10.6.2 คำสั่ง open สามารถส่งอาร์กิวเมนต์ไปยังแอปพลิเคชันที่เปิดขึ้นโดยใช้วิธีการตั้งค่าสถานะ --args AppleScript ที่ใช้งานดูเหมือนว่านี้:

do shell script "open -a /Applications/Firefox.app --args -P default -no-remote"

นั่นควรให้ทุกพฤติกรรมที่คุณต้องการ


"ผู้ชายเปิด" และนั่นคือ! ทำงานเหมือนจับใจ - ค่าสถานะธงแล้วข้อโต้แย้งของคุณ
Michael Dimmitt

1
ฉันลอง--argsกับ Chrome แล้วก็ใช้ไม่ได้ มันจะทำงานสำหรับอินสแตนซ์แรกเท่านั้น หากคุณพยายามเรียกใช้สอง--user-data-dirพร้อมกันคุณจะไม่สามารถทำได้openแต่ต้องเรียกใช้ด้วย/applications...วิธีเก่า ใครรู้ว่าทำไมเพศสัมพันธ์--args ไม่ทำงาน
Pacerier

1
@Pacerier "open -n"
Simon Wright

เพื่อเพิ่มสิ่งนี้คุณสามารถสร้างสคริปต์ใน Script Editor แล้วบันทึกเป็นแอปพลิเคชัน
Kevin C.

11

เปิดAutomatorและสร้างแอปพลิเคชันด้วยการดำเนินการ Run Shell Scriptเดียว:

 /Applications/Firefox.app/Contents/MacOS/firefox-bin -here-some-args &

แอปพลิเคชั่นนี้จะเปิด Firefox และออกทันทีโดยปล่อยให้ Firefox เท่านั้นที่ทำงาน


อีกวิธีหนึ่งคือสร้างแอปพลิเคชันโดยใช้AppleScript Editorด้วยรหัส AppleScript ต่อไปนี้:

do shell script "open -a '/Users/danielbeck/Applications/Firefox.app' --args -ProfileManager"

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


1
เพียงจำไว้ว่าopen --argsมีการใช้งานใน 10.6.2 ตามที่ Bob กล่าวไว้แล้ว
cregox

ใช้สำหรับ: open eclipse.app -nเพื่อเปิดเวิร์กสเปซ Eclipse ที่สอง มีประโยชน์มาก ขอบคุณ!
jonalv

ไม่สามารถทำให้มันทำงานใน Automator ด้วยการกระทำ "Run Shell Script" ใน MacOS 10.14 แต่ท้ายที่สุดฉันก็ประสบความสำเร็จกับ AppleScript
Kevin C.

8

นี่เป็นการสนทนาเก่า แต่ยังปรากฏขึ้นในการค้นหาของ Google ดังนั้นฉันคิดว่าฉันจะเพิ่ม¢สองสามข้อ

มันอาจจะดีกว่าถ้าใช้ "ตัวระบุบันเดิล" แทนที่จะใช้พา ธ สัมบูรณ์ไปยังไฟล์ปฏิบัติการ:

open -b com.google.Chrome --args --profile-directory="Profile 1"

หรือใน Apple Script:

do shell script "open -b com.google.Chrome --args --profile-directory='Profile 1'"

สิ่งที่ฉันยังไม่ได้คิดก็คือวิธีเปิดอินสแตนซ์ / หน้าต่างใหม่ที่มีโปรไฟล์อื่นเมื่อเปิดครั้งแรกแล้ว (ถ้าฉันเรียกใช้ AppleScript ด้านบนก็จะเป็นอีกอันที่มี "โปรไฟล์ 2" ดังนั้น Chrome จะยังคงเปิดหน้าต่างอื่นในชื่อ "โปรไฟล์ 1") :(


-b เท่ากับหน้าที่ -a หรือไม่ แตกต่างกันอย่างไร
Pacerier

7

ไม่จำเป็น (ตามคำตอบอื่น ๆ ที่แนะนำ) เพื่อใช้killall (หรือคล้ายกัน) เพื่อฆ่ากระบวนการแอปพลิเคชัน AppleScript หลัก (“ แอปเพล็”) ในสถานการณ์นี้ มันอาจมีผลข้างเคียงที่ไม่ดีหากชื่อ / รูปแบบที่กำหนดให้killallจับคู่มากกว่ากระบวนการแอปเพล็ตหลัก (เช่นอื่น ๆ ใช้แอปพลิเคชัน AppleScript พร้อมกัน (หากใช้ "แอปเพล็ต" เป็นรูปแบบ))

บางอย่างเช่นkill $PPIDอาจจะเหมาะสมมากขึ้น แต่เราอาจไม่ต้องการที่จะคิดว่าแอปเพล็ของแอพลิเคชัน AppleScript อยู่เสมอผู้ปกครองทันทีของเปลือกที่ตั้งขึ้นโดยทำสคริปต์เชลล์ โชคดีที่มีวิธีที่เหมาะสมที่สุดในการทำสิ่งที่คุณต้องการ

ต่อTN2065 (ภายใต้“ ฉันต้องการเริ่มกระบวนการแบ็คกราวน์เซิร์ฟเวอร์ฉันจะทำให้เชลล์สคริปต์ไม่รอจนกว่าคำสั่งจะเสร็จสมบูรณ์ได้อย่างไร”) วิธีที่เหมาะสมคือเปลี่ยนเส้นทาง stdout และ stderr และให้เชลล์รันโปรแกรมในพื้นหลัง .

ใช้ตัวแก้ไขสคริปต์เพื่อบันทึกโปรแกรมต่อไปนี้เป็นแอปพลิเคชัน AppleScript:

do shell script ¬
    "/Applications/Firefox.app/Contents/MacOS/firefox-bin \\
        -P default -no-remote \\
        >/dev/null 2>&1 &"

(เพิ่มตัวแบ่งบรรทัดการทำงานเพื่อให้“ แคบ”; ลบ¬และ\\และวางทั้งหมดในหนึ่งบรรทัดยาวถ้าคุณต้องการ)

มันจะทำงานได้นานพอที่จะเริ่มFirefoxและจะออกอย่างหมดจดในขณะที่Firefoxยังคงทำงานต่อไป

การเปลี่ยนเส้นทางเป็นสิ่งจำเป็นเพราะเชลล์สคริปต์ไม่เพียง แต่จะรอให้ชายด์ (เชลล์) ออกเท่านั้น แต่ยังจะรอ (อินสแตนซ์ทั้งหมด) ปลายที่เขียนได้ของไพพ์ที่สร้างขึ้นสำหรับ stdout และ stderr ของเชลล์ . stdout และ stderr ของเชลล์ ( ทำไปป์ของเชลล์สคริปต์ ) สืบทอดโดยโปรแกรมที่รันโดยไม่มีการเปลี่ยนเส้นทาง (แม้แต่ที่ทำงานในพื้นหลังด้วย&); การเปลี่ยนเส้นทางทำให้แน่ใจว่าเชลล์เป็นคนสุดท้ายที่จะเก็บปลายของท่อที่เขียนได้ ดังนั้นทำเชลล์สคริปต์จะกลับมาทันทีหลังจากออกจากเชลล์อนุญาตให้แอปพลิเคชัน AppleScript ออกเอง (เนื่องจากสคริปต์เชลล์ทำคือนิพจน์สุดท้ายในโปรแกรม AppleScript)

คำตอบอื่น ๆ ที่ใช้open inside ทำงานเชลล์สคริปต์เพราะopen (จริง ๆ แล้ว LaunchServices) ทำงานเทียบเท่ากับการแบ็คกราวด์โปรแกรมที่เป็นผลลัพธ์และส่ง stdout และ stderr ที่อื่น


มันน่าสนใจมาก ฉันสงสัยว่ามันใช้งานได้ก่อนหน้า 10.6.2 ... แต่ฉันยังคิดว่าการใช้open --argsหน้าตาสะอาดกว่า มีข้อ จำกัด ในการใช้งานใด ๆ ของพวกเขา?
cregox

1
ฉันรู้ว่าวิธีนี้ใช้งานได้ใน 10.4 ความประทับใจของฉันคือเชลล์สคริปต์ทำงานได้อย่างนี้เสมอ (มันถูกเพิ่มไปยังStandard Additions OSAX ในAppleScript 1.7ซึ่งมาพร้อมกับ Mac OS X 10.1) หากคุณยินดีที่จะรับ 10.6 ก็open --argsอาจจะใช้ได้
Chris Johnsen

@ChrisJohnsen เชื่อมโยง ........
Pacerier

4

AppleScript

do shell script "/Applications/Google\\ Chrome.app/Contents/MacOS/Google\\ Chrome --incognito & killall applet"

สองจุดตรงนั้น

  1. ช่องว่างถูกหลบหนีด้วยแบ็กสแลชซึ่งจะหลบหนีโดยแบ็กสแลชอีกครั้ง
  2. แอปเพล็ต killallอาจทำให้เกิดปัญหาเนื่องจากอาจมีแอปเพล็ตอื่น ๆ ที่ทำงานอยู่
  3. บันทึกเป็นโปรแกรม

อย่างไรก็ตามมันทำงานได้ดีบน 10.6.5


appletอ้างถึง?
Pacerier

3

ต่อไปนี้ควรให้คุณระบุอาร์กิวเมนต์บรรทัดคำสั่งสำหรับ. app เอง:

คลิกขวาชุดแอป. เลือก "แสดงเนื้อหาแพ็คเกจ" นำทางไปยัง Info.plist ดับเบิลคลิกเพื่อค้นหาคีย์ Args แก้ไข

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


ไม่มี args ที่สำคัญในการ plist น่าเสียดาย ตาม Mozilla คุณควรใช้สคริปต์ - wiki.mozilla.org/MailNews:Logging#Mac
Andrew

โปรดทราบด้วยว่าการเปลี่ยนแปลงเนื้อหาแพ็คเกจ (เช่น Info.plist) อาจทำให้เกิดปัญหากับการเซ็นรหัส: bridge.grumpy-troll.org/2011/01/…
drevicko

2

ห่อใบสมัครของคุณไว้ในตัวเรียกใช้ AppleScript

นี่คือขั้นตอน

  1. สร้าง AppleScript ด้วยเนื้อหาต่อไปนี้และบันทึกเป็นแอปพลิเคชัน (ในตัวอย่างนี้มีชื่อว่า "Firefox 3 launcher.app")

    set pathToApp to (POSIX path of (path to me)) & "Firefox 3.app"
    do shell script "open -a \"" & pathToApp & "\" --args -P default -no-remote"
    
  2. ไปที่แอพนั้นใน Finder คลิกขวาเพื่อแสดงเนื้อหาของแพ็คเกจ

  3. ใส่ใบสมัครของคุณในรูทของเนื้อหาแพ็คเกจ (ในตัวอย่างนี้จะเป็น "Firefox 3.app")

    ผลลัพธ์: / Applications / Firefox 3 launcher.app/Firefox 3.app

  4. ตอนนี้คุณสามารถเปิดตัวเรียกใช้งานแอปพลิเคชันของคุณได้แล้ว

หมายเหตุ:

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

1

ทำไมคุณไม่ใช้:

#!/bin/sh
open /Applications/Firefox.app

เรียบง่าย แต่ใช้งานได้


2
เทอร์มินัลจะเปิดถ้าคุณทำเช่นนั้น
MJeffryes

0

openคำสั่งมีตัวเลือก--argsอาร์กิวเมนต์ที่คุ้มค่าจะถูกส่งผ่านไปยังโปรแกรมประยุกต์เปิดเป็นข้อโต้แย้ง ตัวอย่างเช่น:

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