Ubah sementara direktori untuk perintah file batch tunggal

19

Dalam shell-scripting jika saya perlu menjalankan perintah dari direktori, saya dapat menggunakan subshell untuk memastikan saya kembali ke konteks aslinya:

(cd temporary/new/directory ; command)
# now I am still in original directory

Apakah ini dapat dilakukan dalam file batch Windows (atau file cmd)

Melakukan hal yang sama dalam file batch membuat saya di direktori baru.

Dapat saya lakukan:

pushd temporary\new\directory && command && popd

Tetapi popd tergantung pada keberhasilan command.

Ada ide?

Greg
sumber
Bagaimana Anda menjalankan "file batch" atau "file cmd"? Jika Anda memasukkan perintah cd ke skrip shell dan menjalankan skrip itu (bukan sumbernya), direktori kerja saat ini dari shell panggilan tidak akan berubah.
garyjohn
Hanya untuk memperjelas ini mengacu pada file batch windows.
Greg
Ini adalah skrip yang menjalankan banyak perintah di berbagai bagian pohon direktori. Beberapa perintah hanya beroperasi pada direktori saat ini. Kembali ke direktori asli membantu menyederhanakan data yang mendorong skrip. Apakah Anda menyarankan untuk membuat file batch terpisah untuk setiap direktori yang harus saya hubungi?
Greg
Seingat saya, Anda merujuk ke skrip shell dan tidak menyebut Windows dalam pertanyaan awal Anda, jadi saya salah berasumsi bahwa Anda menggunakan sistem mirip Unix. Sekarang saya mengerti.
garyjohn
Ya, maaf, saya sadar saya tidak jelas (walaupun saya pikir 'file batch' adalah petunjuk :-p)
Greg

Jawaban:

21

Jika kamu melakukan:

pushd \windows && foobar && popd

Anda akan ditinggalkan (seperti yang Anda nyatakan) di folder \ windows. Mencoba:

pushd \windows & foobar & popd

dan Anda harus menemukan diri Anda kembali ke tempat Anda mulai.

BillP3rd
sumber
1
Ah, jadi single ampersand sama dengan semi-colon di sh. Itu sempurna. (dan referensi: ss64.com/nt/syntax-conditional.html )
Greg
6
Ada baiknya untuk mengingat bahwa cd/ pushdkadang gagal (jika direktori tidak ada, misalnya). pushd \windows && (foobar & popd)mungkin lebih dapat diandalkan
grawity
16

Secara default, file batch Windows dijalankan dalam konteks shell induk (yang tidak biasa bagi pengguna Unix, di mana eksplisit sourcediperlukan, tetapi merupakan satu-satunya kemungkinan dalam MS-DOS). Ini berarti perubahan direktori dan variabel lingkungan juga memengaruhi shell interaktif asli.

Letakkan setlocaldi bagian atas skrip Anda untuk membuatnya berjalan dalam konteksnya sendiri - Anda dapat menggunakan cdskrip dengan aman .

grawity
sumber
Terima kasih, Ini kedengarannya seperti yang saya butuhkan - Saya akan memeriksanya ketika saya mendapatkan akses ke mesin Windows. Apakah itu mempengaruhi sub-perintah menggunakan tanda kurung?
Greg
1
@Reg: Tampaknya ( )hanya perintah grup bersama, tetapi masih menjalankannya dalam konteks induk. (setlocal & cd foo & bar)tidak akan bekerja; sebaliknya pushd foo && (bar & popd)akan dibutuhkan.
grawity
4

Seperti grawity yang disebutkan sebelumnya, pushd \windows && (foobar & popd)akan bekerja lebih baik daripada pushd \windows & foobar & popdkarena yang terakhir mungkin gagal jika tidak ada direktori seperti itu.

Selain itu, menggunakan setlocaldan endlocalmemungkinkan Anda memiliki beberapa lingkungan lokal, jadi misalnya Anda dapat memiliki:

setlocal

cd dir

command

endlocal

Sekarang Anda akan kembali ke direktori asli Anda.

Timtech
sumber
3

Anda dapat menggunakan cd -untuk kembali ke direktori kerja sebelumnya. Dan gunakan ;alih-alih &&, maka perintah selanjutnya tidak akan bergantung pada keberhasilan perintah sebelumnya.

$ pwd
/etc
$ cd /var ; pwd ; cd -
/var
$ pwd
/etc
bahamat
sumber
Saya telah memperbarui pertanyaan untuk menjelaskan bahwa saya bertanya tentang skrip Windows batch / shell. Saya tahu bagaimana melakukannya di bawah shell seperti sh :) :)
Greg
Seperti yang ditunjukkan oleh BillP3rd, setara dengan ';' dalam batch-file adalah '&'.
Greg
Ah maaf. Penggunaan garis miring ke depan membuat saya berpikir itu UNIX.
bahamat
1

Saya memuji saran grawity untuk menempatkan setlocaldi awal skrip batch Anda, tetapi saya akan menambahkan fakta bahwa Anda dapat memiliki beberapa, bersarang, setlocal/ endlocalblok, sehingga jawaban yang lebih relevan untuk pertanyaan itu mungkin

@echo off
setlocal
cddir1
  ...
setlocal
cddir2
command
endlocal
:: Now I am back indir1
  ...

Dan, tentu saja, jika Anda ingin perintah dieksekusi hanya jika cdto dir2berhasil, katakan .cddir2&&command

Perhatikan bahwa setlocal/ endlocalblok menciptakan lingkungan terlokalisasi, sehingga variabel apa pun yang Anda atur atau ubah pada blok tersebut akan kembali ke nilai sebelumnya setelah endlocal.

Scott
sumber
0

Anda dapat menyimpan direktori saat ini menjadi variabel. Ubah dan ubah kembali tergantung pada nilai balik dari perintah. BTW,% CD% mengembalikan DIR Anda saat ini.

surfasb
sumber