Saya merasa sulit untuk mengungkapkan pertanyaan dengan tepat, tetapi saya akan memberikan yang terbaik. Saya menggunakan dwm
sebagai manajer jendela default dandmenu
sebagai peluncur aplikasi saya. Saya jarang menggunakan aplikasi GUI selain dari browser saya. Sebagian besar pekerjaan saya dilakukan langsung dari baris perintah. Selain itu, saya penggemar minimalis tentang sistem operasi, aplikasi, dll. Salah satu alat yang tidak pernah saya singkirkan adalah peluncur aplikasi. Terutama karena saya tidak memiliki pemahaman yang tepat tentang cara kerja peluncur aplikasi / apa yang mereka lakukan. Bahkan pencarian internet yang luas hanya menunjukkan penjelasan yang tidak jelas. Yang ingin saya lakukan adalah menyingkirkan bahkan peluncur aplikasi saya karena selain benar-benar menelurkan aplikasi saya sama sekali tidak menggunakannya. Untuk melakukan ini, saya benar-benar ingin tahu cara "benar" memulai aplikasi dari shell. Dimana arti dari "dengan benar" dapat didekati dengan "seperti yang dilakukan peluncur aplikasi".
Saya tahu tentang cara-cara berikut untuk menelurkan proses dari shell:
exec /path/to/Program
ganti shell dengan perintah yang ditentukan tanpa membuat proses barush -c /path/to/Program
meluncurkan proses tergantung shell/path/to/Program
meluncurkan proses tergantung shell/path/to/Program 2>&1 &
luncurkan proses mandiri shellnohup /path/to/Program &
meluncurkan proses mandiri shell dan mengarahkan ulang output kenohup.out
Pembaruan 1: Saya dapat mengilustrasikan misalnya apa dmenu
merekonstruksi dari panggilan berulang ke ps -efl
dalam kondisi yang berbeda. Ini memunculkan shell baru /bin/bash
dan sebagai anak aplikasi ini shell /path/to/Program
. Selama anak itu ada, maka kulitnya akan ada. (Bagaimana mengelola ini di luar saya ...) Sebaliknya jika Anda mengeluarkan nohup /path/to/Program &
dari shell /bin/bash
maka program akan menjadi anak dari shell ini TETAPI jika Anda keluar dari shell ini induk program akan menjadi proses paling atas. Jadi jika proses pertama adalah eg /sbin/init verbose
dan telah PPID 1
maka itu akan menjadi induk program. Inilah yang saya coba jelaskan menggunakan grafik: chromium
diluncurkan via dmenu
, firefox
diluncurkan menggunakan exec firefox & exit
:
systemd-+-acpid
|-bash---chromium-+-chrome-sandbox---chromium-+-chrome-sandbox---nacl_helper
| | `-chromium---5*[chromium-+-{Chrome_ChildIOT}]
| | |-{Compositor}]
| | |-{HTMLParserThrea}]
| | |-{OptimizingCompi}]
| | `-3*[{v8:SweeperThrea}]]
| |-chromium
| |-chromium-+-chromium
| | |-{Chrome_ChildIOT}
| | `-{Watchdog}
| |-{AudioThread}
| |-3*[{BrowserBlocking}]
| |-{BrowserWatchdog}
| |-5*[{CachePoolWorker}]
| |-{Chrome_CacheThr}
| |-{Chrome_DBThread}
| |-{Chrome_FileThre}
| |-{Chrome_FileUser}
| |-{Chrome_HistoryT}
| |-{Chrome_IOThread}
| |-{Chrome_ProcessL}
| |-{Chrome_SafeBrow}
| |-{CrShutdownDetec}
| |-{IndexedDB}
| |-{LevelDBEnv}
| |-{NSS SSL ThreadW}
| |-{NetworkChangeNo}
| |-2*[{Proxy resolver}]
| |-{WorkerPool/1201}
| |-{WorkerPool/2059}
| |-{WorkerPool/2579}
| |-{WorkerPool/2590}
| |-{WorkerPool/2592}
| |-{WorkerPool/2608}
| |-{WorkerPool/2973}
| |-{WorkerPool/2974}
| |-{chromium}
| |-{extension_crash}
| |-{gpu-process_cra}
| |-{handle-watcher-}
| |-{inotify_reader}
| |-{ppapi_crash_upl}
| `-{renderer_crash_}
|-2*[dbus-daemon]
|-dbus-launch
|-dhcpcd
|-firefox-+-4*[{Analysis Helper}]
| |-{Cache I/O}
| |-{Cache2 I/O}
| |-{Cert Verify}
| |-3*[{DOM Worker}]
| |-{Gecko_IOThread}
| |-{HTML5 Parser}
| |-{Hang Monitor}
| |-{Image Scaler}
| |-{JS GC Helper}
| |-{JS Watchdog}
| |-{Proxy R~olution}
| |-{Socket Thread}
| |-{Timer}
| |-{URL Classifier}
| |-{gmain}
| |-{localStorage DB}
| |-{mozStorage #1}
| |-{mozStorage #2}
| |-{mozStorage #3}
| |-{mozStorage #4}
| `-{mozStorage #5}
|-gpg-agent
|-login---bash---startx---xinit-+-Xorg.bin-+-xf86-video-inte
| | `-{Xorg.bin}
| `-dwm-+-dwmstatus
| `-xterm---bash-+-bash
| `-pstree
|-systemd---(sd-pam)
|-systemd-journal
|-systemd-logind
|-systemd-udevd
|-wpa_actiond
`-wpa_supplicant
Pembaruan 2: Saya kira pertanyaannya juga dapat dirubah menjadi: Apa yang seharusnya menjadi induk dari suatu proses? Haruskah misalnya menjadi shell atau haruskah init
proses yaitu proses dengan PID 1
?
init
- yang jawabannya mungkin ... mungkin? itu tergantung pada bagaimana / jika Anda berencana untuk berbicara dengannya, apa yanginit
Anda gunakan, dan di mana saluran data berada. Secara umum hal-hal itu akan cenderung bekerja dengan sendirinya - itulah gunanyainit
. Dalam kasus apa pun, biasanya ketika Anda melakukan daemonisasi suatu prosesinit
. Atau jika Anda ingin kontrol pekerjaan, shell saat ini.dmenu
dan melihat bagaimana saya cocok dengan apa yang saya pelajari. Saya menemukanexec /path/to/Program & exit
atau/bin/bash -c /path/to/Program & exit
cukup berguna. Tapi mereka semua make1
yaituinit
induk dariProgram
yang baik-baik saja dengan saya selama ini masuk akal dan tidak melanggar dasar*nix
prinsip-prinsip.exec &
, saya pikir. Saya biasanya hanya melakukan barang-barang saya dari terminal ... mungkin Anda akan menggunakan pertanyaan ben crowell di sini . Saya punya jawaban di sana, tetapi semuanya sangat bagus. Lagi pula, ketika Anda melatar belakangi suatu proses dan orangtuanya mati seperti:sh -c 'cat & kill $$'
Anda menjadi yatim piatu, dan akhirnya akan menuai akhirnya. itu pekerjaan init - itu sebabnya mereka semua jatuh ke dalamnya.systemd--bash--chromium
. Semua metode yang saya coba pada akhirnya akan mengarah ke pohon proses dari bentuk berikutsystemd--chromium
ketika saya menelurkan firefox dari shell. Bagaimana cangkang ini di iblis di sini? Itu tidak terkait dengan terminal apa pun.Jawaban:
Sepertinya Anda memiliki pemahaman yang cukup bagus tentang itu. Untuk memperjelas beberapa yang Anda miliki,
sh -c /path/to/Program
cukup mirip dengantempat Anda memulai proses shell baru, berikan jalur perintah aplikasi ke shell baru, dan kemudian biarkan shell baru berakhir. Saya telah menunjukkan shell baru memberikan prompt yang berbeda untuk tujuan ilustrasi; ini mungkin tidak akan terjadi dalam kehidupan nyata. The membangun sebagian besar berguna untuk melakukan hal-hal yang rumit, seperti membungkus beberapa perintah ke dalam sebuah kemasan, sehingga mereka terlihat seperti satu perintah (semacam script yang tidak disebutkan namanya sekali pakai), atau bangunan yang rumit perintah, mungkin dari variabel shell. Anda tidak akan pernah menggunakannya hanya untuk menjalankan satu program dengan argumen sederhana.
sh -c "command"
2>&1
berarti mengarahkan kesalahan standar ke output standar. Ini tidak benar-benar ada hubungannya dengan&
; alih-alih, Anda menggunakannya ketika perintah mengirim pesan kesalahan ke layar meskipun Anda mengatakan dan ingin menangkap pesan kesalahan dalam file.command > file
nohup.out
adalah efek samping sepele darinohup
. Tujuan utama adalah untuk menjalankan secara tidak sinkron (umumnya dikenal sebagai "di latar belakang", atau sebagai "proses mandiri shell", untuk menggunakan kata-kata Anda) dan mengkonfigurasinya sehingga memiliki peluang yang lebih baik untuk dapat terus berjalan jika Anda menghentikan shell (mis., logout) saat perintah masih berjalan.nohup command &
command
bash(1)
dan Bash Reference Manual adalah sumber informasi yang bagus.sumber
Ada beberapa cara untuk menjalankan program dan melepaskannya dari terminal. Pertama adalah menjalankannya di latar subkulit , seperti ini (ganti
firefox
dengan program favorit Anda):Cara lain adalah menolak proses:
Jika Anda ingin tahu tentang bagaimana peluncur aplikasi kerja,
dmenu
menyediakan 1 biner dan 2 shell script:dmenu
,dmenu_path
dandmenu_run
masing-masing.dmenu_run
dmenu_path
mem -pipe output ke dalam dmenu, yang pada gilirannya pipa menjadi apa pun$SHELL
variabel Anda diatur. Jika kosong, itu akan digunakan/bin/sh
.dmenu_path
sedikit lebih rumit, tetapi singkatnya menyediakan daftar binari dalam$PATH
variabel lingkungan Anda , dan menggunakan cache jika memungkinkan.Tidak perlu menjalankan program dalam shell. Cara lain untuk menulis
dmenu_run
, tanpa menyalurkan ke shell adalah:sumber
Saya suka jawaban G-Man. Tetapi saya merespons karena saya pikir Anda memiliki masalah yang membingungkan. Seperti yang ditunjukkan Wayne, jawaban terbaik adalah "apa pun yang mendapatkan hasil yang Anda inginkan".
Dalam manajemen proses Unix, setiap proses memiliki orang tua. Satu-satunya pengecualian untuk ini adalah
init
proses yang dimulai oleh OS saat boot. Ini adalah perilaku normal untuk proses induk untuk mengambil semua proses anak itu dengan itu ketika mati. Ini dilakukan dengan mengirimkan sinyal SIGHUP ke semua proses anak; penanganan default SIGHUP menghentikan proses.Pemijahan shell dari proses pengguna tidak berbeda dengan jika Anda mengkodekan panggilan fork (2) / exec (3) dalam bahasa pilihan Anda. Shell adalah orang tua Anda, dan jika shell berakhir (misalnya, Anda log off), maka child process akan muncul. Nuansa yang Anda gambarkan hanyalah cara memodifikasi perilaku itu.
exec /path/to/program
seperti memanggil exec (3) . Ya, itu akan mengganti shell Anda denganprogram
, menjaga induk apa pun meluncurkan shell.sh -c /path/to/program
semacam tanpa tujuan membuat proses shell anak yang akan membuat proses anakprogram
. Ini hanya bernilai jika/path/to/program
sebenarnya merupakan urutan instruksi skrip, dan bukan file yang dapat dieksekusi. (sh /path/to/script.sh
dapat digunakan untuk menjalankan skrip shell yang tidak memiliki izin eksekusi di shell yang lebih rendah)/path/to/program
menciptakan proses "foreground", yang berarti bahwa shell menunggu proses untuk menyelesaikan sebelum mengambil tindakan lain. Dalam konteks system call, itu seperti fork (2) / exec (3) / waitpid (2) . Perhatikan bahwa anak mewarisi stdin / stdout / stderr dari orang tua./path/to/program &
(mengabaikan pengalihan) menciptakan "proses latar belakang". Prosesnya masih anak-anak dari shell, tetapi orang tua tidak menunggu untuk mengakhiri.nohup /path/to/program
meminta nohup (1) untuk mencegah pengiriman SIGHUPprogram
jika terminal pengendali ditutup. Apakah itu di latar depan atau latar belakang adalah pilihan (meskipun paling umum prosesnya adalah latar belakang). Perhatikan bahwanohup.out
hanya output jika Anda tidak mengarahkan stdout.Saat Anda meletakkan proses di latar belakang, jika proses induk mati, salah satu dari dua hal terjadi. Jika orang tua adalah terminal pengendali , maka SIGHUP akan dikirim ke anak-anak. Jika tidak, maka prosesnya mungkin "yatim piatu", dan diwarisi oleh
init
proses tersebut.Ketika Anda mengarahkan input / output / kesalahan, Anda cukup menghubungkan deskriptor file yang setiap proses memiliki file yang berbeda dari yang diwarisi dari induknya. Tidak satu pun dari ini yang mempengaruhi kepemilikan proses atau kedalaman pohon (tetapi selalu masuk akal untuk mengarahkan semua 3 jauh dari terminal untuk proses latar belakang).
Dengan semua yang dikatakan, saya tidak berpikir Anda harus peduli dengan pembuatan proses oleh shell atau sub-shell atau sub-proses, kecuali ada masalah khusus yang Anda atasi terkait dengan manajemen proses.
sumber
sh -c /path/to/program
tidak akan menjalankan program sebagai skrip shell jika tidak ada bit yang dapat dieksekusish /path/to/program
.sh -c /path/to/program
hanya akan membuka shell dan menjalankan/path/to/program
sebagai perintah di shell itu, yang akan gagal jika itu tidak dapat dieksekusi.sh -c /path/to/program
membaca perintah dari/path/to/program
sebagai input ke shell. Itu tidak mengharuskan file tersebut memiliki izin mengeksekusi tetapi itu harus skrip shellsh /path/to/program
lakukan itu. Coba saja sendiri :,echo echo hello world >abc.sh
lalush ./abc.sh
cetakhello world
, sambilsh -c ./abc.sh
berkatash: ./abc.sh: Permission denied
(yang sama seperti jika Anda akan menjalankan./abc.sh
shell saat ini secara langsung.) Apakah saya melewatkan sesuatu? (Atau mungkin saya tidak mengekspresikan diri dengan baik di komentar sebelumnya ...)sh -c _something_
sama dengan hanya mengetik_something_
di prompt perintah, kecuali untuk pemijahan shell inferior. Jadi Anda benar bahwa itu akan gagal jika melewatkan bit eksekusi (sebagai file). Di sisi lain, Anda dapat memberikan serangkaian perintah shell sepertish -c "echo hello world"
dan itu akan berfungsi dengan baik. Jadi itu tidak mengharuskan apa yang Anda ketik memiliki bit eksekusi (atau bahkan menjadi file), hanya saja shell interpreter dapat melakukan sesuatu dengannya.