Bagaimana cara menjalankan program dengan direktori kerja yang berbeda dari saat ini, dari Linux shell?

352

Menggunakan shell Linux , bagaimana cara memulai program dengan direktori kerja yang berbeda dari direktori kerja saat ini?

Sebagai contoh, saya memiliki file biner helloworldyang membuat file hello-world.txtdi direktori saat ini .

File ini ada di dalam direktori /a.

Saat ini, saya berada di direktori /b. Saya ingin menjalankan program saya ../a/helloworlddan mendapatkan hello-world.txttempat di direktori ketiga /c.

Anton Daneyko
sumber
5
Saya menemukan cara sulit yang sume-reset direktori kerja ke direktori home pengguna yang Anda tentukan sebelum menjalankan -cperintah apa pun . Ini sangat membantu saya.
Patrick M

Jawaban:

561

Panggil program seperti ini:

(cd /c; /a/helloworld)

Tanda kurung menyebabkan sub-shell untuk melahirkan. Sub-shell ini kemudian mengubah direktori kerjanya menjadi /c, lalu mengeksekusi helloworlddari /a. Setelah program keluar, sub-shell berakhir, mengembalikan Anda ke prompt Anda dari shell induk, di direktori Anda mulai.

Penanganan kesalahan: Untuk menghindari menjalankan program tanpa mengubah direktori, mis. Ketika salah eja /c, lakukan eksekusi dengan helloworldsyarat:

(cd /c && /a/helloworld)

Mengurangi penggunaan memori: Untuk menghindari hilangnya memori subkulit saat hello world dieksekusi, panggil helloworldvia exec:

(cd /c && exec /a/helloworld)

[Terima kasih kepada Josh dan Juliano karena telah memberi tip untuk meningkatkan jawaban ini!]

David Schmitt
sumber
1
Adakah cara untuk menyampaikan argumen ke shell ini? Seperti dalam $ 1, dan $ 2?
finiteloop
2
@segfault: Subshell memiliki akses lengkap ke ruang lingkup di sekitarnya.
David Schmitt
Sepertinya itu sementara di direktori itu, bukan?
dhein
1
Anda dapat melewati semua argumen dengan melakukan $ *, $ @ atau "$ @" (jika Anda ingin argumen untuk menghormati tanda kutip ganda)
Marcel Valdez Orozco
1
Apakah akan berfungsi jika saya menambahkan baris ini ke /etc/rc.d/rc.local?
Pratik Patil
95

Mirip dengan jawaban David Schmitt , ditambah saran Josh, tetapi tidak membiarkan proses shell berjalan:

(cd /c && exec /a/helloworld)

Cara ini lebih mirip dengan cara Anda biasanya menjalankan perintah di shell. Untuk melihat perbedaan praktis, Anda harus lari ps efdari shell lain dengan setiap solusi.

Juliano
sumber
Bash manual builtins exec
Antonios Hadjigeorgalis
25

Opsi yang tidak memerlukan subkulit dan dibangun untuk mem-bash

(pushd SOME_PATH && run_stuff; popd)

Demo:

$ pwd
/home/abhijit
$ pushd /tmp # directory changed
$ pwd
/tmp
$ popd
$ pwd
/home/abhijit
Loren
sumber
1
Saran serupa telah dilakukan di bawah ini oleh Sahil. Ini tidak berfungsi jika perintah gagal. Pertimbangkan pushd SOME_PATH && run_stuff && popd- jika run_stuff gagal, maka popd tidak akan dieksekusi.
Anton Daneyko
Balasan terlambat, itu tergantung pada pengaturan file bash. Bash dapat melanjutkan menjalankan perintah bahkan setelah perintah gagal (tidak seperti menggunakan &&), tetapi dapat diatur untuk tidak melakukan itu menggunakan set -edalam file dan kemudian akan gagal popd.
Loren
8
Namun, saya pikir pushd "${SOME_PATH}" && run_stuff; popdlebih baik daripada jawaban saat ini, karena semantik pushd / popd secara khusus dirancang untuk situasi ini masuk ke beberapa direktori dan kemudian kembali ke yang asli.
Marcel Valdez Orozco
Bagaimana cara kerjanya sebagaimana didefinisikan sebagai alias dan saya harus melewati param?
DrB
Saya pikir Anda harus menulis skrip shell di mana Anda akan melewatkan parameter yang akan menjalankan serangkaian perintah karena Anda tidak dapat melewati parameter di tengah alias. Jika Anda perlu bantuan menulis itu, Anda harus mengajukan pertanyaan terpisah dan referensi yang satu ini. Setelah memiliki skrip shell, Anda dapat menulis alias untuk memanggil skrip baru Anda.
Loren
19
sh -c 'cd /c && ../a/helloworld'
mihi
sumber
1
Menggunakan ini untuk jexec FreeBSD untuk menjalankan perintah di dalam penjara di direktori kerja yang ditentukan.
Marián Černý
11

Saya selalu berpikir alat UNIX harus ditulis sebagai filter, membaca input dari stdin dan menulis output ke stdout. Jika memungkinkan Anda bisa mengubah biner helloworld Anda untuk menulis konten file teks ke stdout daripada file tertentu. Dengan begitu Anda bisa menggunakan shell untuk menulis file Anda di mana saja.

$ cd ~ / b

$ ~ / a / helloworld> ~ / c / helloworld.txt

Luther Blisset
sumber
6
+1 karena benar, meskipun jawabannya hanya merupakan jawaban periferal.
David Schmitt
8

Ubah saja "&&" terakhir menjadi ";" dan itu akan cd kembali tidak masalah jika perintah gagal atau berhasil:

cd SOME_PATH && run_some_command ; cd -
johnnybravo
sumber
4

Salah satu cara untuk melakukannya adalah dengan membuat skrip shell wrapper.

Script shell akan mengubah direktori saat ini ke / c, kemudian jalankan / a / helloworld. Setelah skrip shell keluar, direktori saat ini kembali ke / b.

Berikut contoh skrip bash shell:

#!/bin/bash
cd /c
/a/helloworld
Jin Kim
sumber
2

mengapa tidak menjaganya tetap sederhana

cd SOME_PATH && run_some_command && cd -

perintah 'cd' terakhir akan membawa Anda kembali ke direktori pwd terakhir. Ini harus bekerja pada semua sistem * nix.

Sahil
sumber
Anda menulis @mezhaka, seharusnya sudah mempertimbangkan itu :)
Sahil
1
Peringatan: Jika run_some_commandgagal, cd -tidak akan dieksekusi.
starbeamrainbowlabs
1

Jika Anda selalu ingin ke / C, gunakan jalur absolut saat Anda menulis file.

Tom Ritter
sumber
0

Jika Anda ingin melakukan ini di dalam program Anda maka saya akan melakukan sesuatu seperti:

#include <unistd.h>
int main()
{
  if(chdir("/c") < 0 )  
  {
     printf("Failed\n");
     return -1 ;
  }

  // rest of your program...

}
Harold
sumber
Dia ingin melakukan itu di shell-script, dan bukan di C. Juga, itu akan menjadi ide yang mengerikan untuk memproses file biner.
-1

dari direktori saat ini, berikan path lengkap ke direktori script untuk menjalankan perintah

/root/server/user/home/bin/script.sh
Ravi Bhushan
sumber
1
Itu sama sekali tidak mengubah direktori kerja - saya pikir Anda menjawab pertanyaan yang berbeda dengan yang ditanyakan.
Toby Speight
Datang ke sini untuk menemukan jawaban atas pertanyaan yang Anda jawab. Terima kasih! lol
kfrncs