Mendapatkan launchd untuk membaca argumen program dengan benar

18

Saya memiliki skrip launchd di mana perintah yang saya coba jalankan salah (ternyata itu bukan kata, sekarang), mengeluhkan penggunaan yang tidak benar.

Kesalahan spesifik yang saya dapatkan adalah teks penggunaan perintah dibuang ke log sistem. Dari sini saya menyimpulkan info lain (path ke perintah, waktu dll) dalam daftar sedang diurai dengan benar, hanya saja bukan opsi perintah.

Setelah penggunaan perintah saya memiliki satu baris terakhir:

18/11/2013 09:30:00.101 com.apple.launchd.peruser.501: (fake.lable.seti[33833]) Exited with code: 1

Tapi itu hanya berarti "Saya keluar dengan kesalahan".

Saya tahu launchd memisahkan perintah dari opsinya dan di halaman manual memberi tahu Anda tentang ProgramArguments: "... Harap dicatat: banyak orang bingung dengan kunci ini. Harap baca execvp (3) dengan sangat hati-hati! .."

Yah saya membaca execvp (3) dan saya bukan orang yang lebih bijak, jadi saya banyak bertanya kepada Anda.

Biasanya, menjalankan perintah dari terminal akan terlihat seperti ini:

/Library/Application\ Support/BOINC\ Data/boinccmd --host localhost --passwd gobbledygook --project http://setiathome.berkeley.edu/ update

Ini berhasil.

Dan ini adalah bagaimana saya membaginya di bagian Program / ProgramArguments dari daftar LaunchAgent saya:

<key>Program</key>
    <string>/Library/Application Support/BOINC Data/boinccmd</string>
<key>ProgramArguments</key>
    <array>
        <string>--host localhost</string>
        <string>--passwd gobbledygook</string>
        <string>--project http://setiathome.berkeley.edu/ update</string>
    </array>

(sebagai catatan, saya awalnya memiliki jalan menuju boinccmd \ lolos, tetapi itu tidak berhasil, launchd lolos dari ruang di jalur untuk Anda)

Saya sudah mencoba memisahkan argumen ke bawah:

<key>Program</key>
    <string>/Library/Application Support/BOINC Data/boinccmd</string>
<key>ProgramArguments</key>
    <array>
        <string>--host</string>
        <string>localhost</string>
        <string>--passwd</string>
        <string>gobbledygook</string>
        <string>--project</string>
        <string>http://setiathome.berkeley.edu/</string>
        <string>update</string>
    </array>

Tapi sepertinya itu juga tidak berhasil.

Seperti biasa, saya sangat yakin saya kehilangan sesuatu yang begitu sederhana.

Terima kasih.


MENJAWAB:

Baris pertama dari ProgramArguments perlu menjadi jalur ke program. Inilah yang membuat saya tersandung dan memang apa yang mungkin dimaksud dengan komentar "... Mohon baca dengan saksama! .." :) Saya juga menemukan saya harus membagi argumen menjadi beberapa bagian komponen. Ketika saya memiliki semua itu di tempat semuanya bekerja pesona. Terima kasih banyak.

<key>Program</key>
    <string>/Library/Application Support/BOINC Data/boinccmd</string>
<key>ProgramArguments</key>
    <array>
        <string>/Library/Application Support/BOINC Data/boinccmd</string>
        <string>--host</string>
        <string>localhost</string>
        <string>--passwd</string>
        <string>gobbledygook</string>
        <string>--project</string>
        <string>http://setiathome.berkeley.edu/</string>
        <string>update</string>
    </array>

Hasil edit terakhir untuk penjelasan yang mudah dimengerti MENGAPA ini seharusnya, lihat penjelasan SirPavlova.

~ W

Woodgie
sumber
Menggunakan daftar launchctl com.label.plist saya dapat melihat bahwa launchd mendapatkan bagian yang benar dari perintah untuk disatukan. Saya berpikir mungkin itu adalah masalah yang terkait dengan -, tetapi ternyata tidak.
Woodgie
1
Saya tidak punya jawaban untuk masalah Anda, tetapi contoh pertama Anda dengan <string>--host localhost</string>pasti tidak akan berfungsi. Ingat, ketika Anda menulis baris perintah ke shell, ia tidak tahu apa yang menjadi bagian dari opsi dan apa argumen reguler - hanya terpecah pada spasi sebelum meneruskan argumen ke program yang sedang dijalankan. Selain itu, mungkin membantu jika Anda menunjukkan kesalahan yang boinccmddilaporkan.
Kevin Reid
Mengedit posting saya untuk mengatakan apa yang saya lihat. Bukan berarti itu akan membantu! Juga, saya mendapatkan kesalahan yang sama jika saya membagi opsi pada spasi putih mereka. Saya kira itu - yang menyebabkan masalah.
Woodgie
1
Saya akan mencoba menggunakan hanya Program atau Dokumen Program tidak keduanya
user151019

Jawaban:

19

The Programkey menentukan file untuk mengeksekusi, & yangProgramArguments utama menentukan argumen yang akan diteruskan ke proses mengeksekusi. Sebenarnya Anda dapat melewati argumen apa pun yang Anda inginkan untuk suatu proses, tetapi konvensi adalah bahwa yang pertama haruslah nama yang dengannya proses itu dijalankan, sehingga sebagian besar program mengabaikan argumen pertama mereka. File yang akan dieksekusi jelas merupakan informasi yang diperlukan, tetapi jika Programkuncinya hilang, launchd berpura-pura memiliki nilai yang sama dengan argumen pertama ProgramArguments semata-mata sebagai kenyamanan .

Contoh pertama Anda mulai boinccmd & memberikan argumen yang setara dengan perintah terminal

--host\ localhost --passwd\ gobbledygook --project\ http://setiathome.berkeley.edu/\ update

yang memberitahu boinccmd bahwa Anda memanggilnya sebagai "--host localhost" & hanya memberikan dua argumen aneh.

Contoh kedua Anda memisahkan argumen dengan benar, tetapi seperti yang disarankan Eddie Kelley, argumen itu perlu dimasukkan di depan. Ia memberi tahu boinccmd bahwa Anda memanggilnya sebagai "--host", lalu memberikan enam argumen lagi. boinccmd dapat mengenali lima terakhir sebagai dua opsi, tetapi tidak tahu apa arti bisnis "localhost". Sejauh yang diketahui boinccmd, itu dipanggil dari terminal sebagai

/Library/Application\ Support/BOINC\ Data/boinccmd localhost --passwd gobbledygook --project http://setiathome.berkeley.edu/ update

(perhatikan "--host" yang hilang).

boinccmd mungkin salah satu dari sebagian besar program yang tidak peduli apa argumen pertama mereka, jadi Anda mungkin bisa benar-benar hanya mendorong <string>HELLO</string>di bagian atas ProgramArgumentsarray, tetapi mungkin lebih bersih untuk menghapus Programkunci sama sekali & cukup gunakan ini:

<key>ProgramArguments</key>
    <array>
        <string>/Library/Application Support/BOINC Data/boinccmd</string>
        <string>--host</string>
        <string>localhost</string>
        <string>--passwd</string>
        <string>gobbledygook</string>
        <string>--project</string>
        <string>http://setiathome.berkeley.edu/</string>
        <string>update</string>
    </array>

Ini bisa terlihat seperti redundansi yang tidak berarti, tetapi beberapa program menggunakan ini untuk efek yang baik: bash et al. bertindak sebagai shell login jika argumen pertama mereka dimulai dengan -, & Vim memasuki berbagai mode emulasi jika argumen pertamanya adalah edatau vibukan vim.

SirPavlova
sumber
1
Anda memposting karena saya mengedit posting utama saya! Ini penjelasan yang bagus. Terima kasih.
Woodgie
1
Senang bisa membantu :)
SirPavlova
@ SirPavlova, sangat membantu! Namun, apakah ada alat yang membantu orang untuk mengubah permintaan konsol ke format plist?
gaussblurinc
6

Berdasarkan halaman manual untuk exec (3), tampaknya argumen program pertama harus menjadi jalur ke executable:

The execv(), execvp(), and execvP() functions provide an array of pointers to null-terminated strings
 that represent the argument list available to the new program.  The first argument, by convention,
 should point to the file name associated with the file being executed. The array of pointers must be
 terminated by a NULL pointer.

Jika Anda dapat menentukan path ke executable sebagai argumen di indeks 0, itu mungkin membantu ...

Eddie Kelley
sumber
Saat saya mengedit pos untuk ditampilkan, boinccmd ditemukan dan dijalankan, opsi yang diteruskan ke sana entah bagaimana sedang rusak. Kecuali saya tidak mengerti apa yang Anda katakan.
Woodgie
1
@ Woodgie Ya yang ditemukan di Program - ProgramArguments Anda salah, perlu nama path yang dapat dieksekusi
user151019
Oh OH! Saya rasa saya mengerti sekarang. Tunggu sebentar, coba itu.
Woodgie
BINGO, melakukan itu dan menempatkan setiap bagian dari setiap perintah dalam wadah <string> </string> sendiri berfungsi. Terima kasih. SAYA MENGATAKAN itu sederhana!
Woodgie