Jalankan perintah tertentu dalam direktori yang diberikan tanpa melakukannya?

42

Apakah ada cara untuk mengeksekusi perintah di direktori yang berbeda tanpa harus melakukannya cd? Saya tahu bahwa saya bisa cdmasuk dan cdkeluar, tetapi saya hanya tertarik pada kemungkinan untuk menghentikan langkah-langkah tambahan :)

Naftuli Kay
sumber
Ini agak sepele untuk membuat script yang melakukan ini: echo "#!/bin/bash; cd $1; exec $2" > /usr/local/bin/execindirectory; chmod +x /usr/local/bin/execindirectory. Mungkin perlu sedikit usaha jika Anda ingin itu benar-benar mendukung opsi "tag" seperti -ddan lainnya.
LawrenceC
Seperti yang tidak diketahui pengguna dalam jawaban, semua contoh yang Anda berikan di sini dan di komentar lebih baik ditangani oleh solusi lain, jadi tidak jelas apakah sebenarnya ada masalah yang perlu diselesaikan di sini. Bisakah Anda memberikan contoh yang lebih baik?
Caleb

Jawaban:

55

Saya tidak tahu apakah ini penting, tetapi Anda dapat membuat subkulit:

$ (cd /var/log && cp -- *.log ~/Desktop)

Direktori hanya diubah untuk subkulit itu, sehingga Anda menghindari pekerjaan yang perlu dilakukan cd -setelahnya.

Michael Mrozek
sumber
2
Itulah yang biasanya saya lakukan.
Adam Byrtek
Bagus, saya sudah lupa sama sekali tentang sub-shell, sangat berguna dalam hal ini.
Naftuli Kay
4
Untuk menghindari potensi kekacauan, sub keluar titik koma dengan dua ampersands: $ (cd /var/log && cp *.log ~/Desktop). Dengan begitu, jika direktori tidak ada, tidak ada perintah lebih lanjut yang dijalankan.
Naftuli Kay
Catatan untuk orang lain yang sama naifnya dengan saya: $ at start bukan bagian dari perintah, hanya semuanya setelahnya.
Maltronic
14

Beberapa program memiliki pilihan yang Anda dapat memberitahu mereka untuk chdir (2) diri mereka sendiri (misalnya GNU tar ‘s -C/ --directory).

Di luar program semacam itu, sesuatu harus chdir . Anda dapat menulis dan menggunakan semacam program "biner" yang dikompilasi alih-alih membuat shell melakukannya, tetapi mungkin tidak akan menghasilkan banyak manfaat.

Dalam komentar di jawaban lain, Anda memberi contoh:

execindirectory -d /var/log "cp *.log ~/Desktop"

Karena *.logpolanya diperluas oleh shell itu sendiri (bukan cp ), sesuatu harus chdir ke direktori sebelum shell mengevaluasi perintah Anda.

Jika Anda hanya tertarik untuk menghindari "cd back", maka Anda dapat menggunakan subshell untuk mengisolasi efek dari cd dari instance shell Anda.

(cd /path/to/dir && some command)

Anda dapat mengemas ini dalam fungsi shell. (Saya menjatuhkan -dopsi dari contoh penggunaan Anda karena ada sedikit poin untuk perintah ini jika direktori sebenarnya opsional.)

runindir() { (cd "$1" && shift && eval "$@"); }

runindir /var/log 'cp *.log ~/Desktop'  # your example
runindir /var/log cp \*.log \~/Desktop  # eval takes multiple args

runindir /var/log cp \*.log ~/Desktop   # it is okay to expand tilde first
Chris Johnsen
sumber
2
Saya suka solusi ini, kecuali, secara pribadi saya akan menggunakan pushd / popd
NJ
10

Bukan untuk merusak nilai jawaban yang diberikan oleh orang lain, tapi saya yakin yang Anda inginkan adalah ini:

(cd /path/to && ./executable [ARGS])

Perhatikan parens yang akan dipanggil cddalam sub-shell.

alex
sumber
Saya kira tidak. Seperti yang saya mengerti, dia ingin berakhir di direktori awal.
Adam Byrtek
Oh, saya benar-benar lupa untuk membungkusnya menjadi sub-shell. Mengoreksi jawaban saya, terima kasih.
alex
4

Ini adalah sesuatu yang seharusnya membuat Anda cdkembali ke tempat Anda sebelumnya (menggunakan Bash), karena tidak lupa untuk melakukannya sepertinya menjadi tujuan pertanyaan:

# Save where you are and cd to other dir
pushd /path/to/dir/that/needs/to/be/current/dir

run-your-command

# Get back where you were at the beginning.
popd

(EDIT: versi yang sedikit lebih pendek, terima kasih kepada @ Random832)

Bruno
sumber
1
Anda bisa pushd other-dir, alih-alihpushd .; cd other-dir
Random832
@ Random832, poin bagus!
Bruno
2

Sayangnya, contoh Anda:

execindirectory -d /var/log "cp *.log ~/Desktop"

tidak perlu perubahan ke dir, karena

cp /var/log/*.log ~/Desktop

akan melakukan hal yang sama. Tidak bisakah Anda mendekati masalah Anda yang sebenarnya? Karena kita mungkin tahu solusi yang lebih baik untuk itu juga.

Cara rumit untuk menyelesaikan masalah Anda, yang jauh dari keanggunan solusi Michaels, adalah penggunaan find, yang memiliki sakelar '-execdir' untuk dijalankan dalam direktori, tempat file ditemukan. Diadopsi dengan buruk untuk contoh Anda:

find /var/log -maxdepth 1 -type f -name "*.log" -execdir echo cp {} ~/Desktop ";"

Mungkin ini berguna untuk masalah Anda yang sebenarnya. -okdir bukannya -execdir akan meminta Anda untuk mengonfirmasi setiap doa.

-okdir dan -execdir mungkin perlu diinstal gnu-find, yang biasanya digunakan di Linux.

Pengguna tidak diketahui
sumber
1

Bagaimana dengan ./your/path/command.sh?

bdictator
sumber
Tidak, aku benar-benar berarti sesuatu seperti berikut ini: execindirectory -d /var/log "cp *.log ~/Desktop".
Naftuli Kay
Saya sangat menyadari bahwa ini tidak sepenuhnya diperlukan, omong-omong, saya hanya tertarik jika itu benar-benar dapat dilakukan.
Naftuli Kay