Mengalihkan Output dari dalam file Batch

110

Saya membuat file batch dengan beberapa perintah sederhana untuk mengumpulkan informasi dari sistem. File batch berisi perintah untuk mendapatkan waktu, informasi IP, pengguna, dll.

Saya mengumpulkan semua perintah dalam file batch, dan itu berjalan, tetapi saya ingin file batch, ketika dijalankan untuk menampilkan hasilnya ke file teks (log). Apakah ada perintah yang dapat saya tambahkan ke batch yang akan melakukannya?

Perlu diingat bahwa saya tidak ingin menjalankan batch dari cmd, lalu alihkan keluaran; Saya ingin mengarahkan output dari dalam batch, jika memungkinkan.

pengguna3085030
sumber

Jawaban:

161

Cara naif sederhana yang lambat karena membuka dan memposisikan penunjuk file ke End-Of-File beberapa kali.

@echo off
command1 >output.txt
command2 >>output.txt
...
commandN >>output.txt

Cara yang lebih baik - lebih mudah untuk menulis, dan lebih cepat karena file dibuka dan diposisikan hanya sekali.

@echo off
>output.txt (
  command1
  command2
  ...
  commandN
)

Cara lain yang baik dan cepat yang hanya membuka dan memposisikan file sekali

@echo off
call :sub >output.txt
exit /b

:sub
command1
command2
...
commandN

Sunting 2020-04-17

Sesekali Anda mungkin ingin berulang kali menulis ke dua file atau lebih. Anda mungkin juga menginginkan pesan yang berbeda di layar. Masih mungkin untuk melakukan ini secara efisien dengan mengarahkan ke tuas yang tidak ditentukan di luar blok atau subrutin yang diberi tanda kurung, lalu menggunakan &notasi untuk mereferensikan file yang sudah dibuka.

call :sub 9>File1.txt 8>File2.txt
exit /b

:sub
echo Screen message 1
>&9 File 1 message 1
>&8 File 2 message 1
echo Screen message 2
>&9 File 1 message 2
>&8 File 2 message 2
exit /b

Saya memilih untuk menggunakan pegangan 9 dan 8 dalam urutan terbalik karena cara itu lebih cenderung menghindari potensi pengalihan permanen karena cacat desain implementasi pengalihan Microsoft saat melakukan beberapa pengalihan pada perintah yang sama. Ini sangat tidak mungkin, tetapi bahkan pendekatan itu dapat mengekspos bug jika Anda berusaha cukup keras. Jika Anda melakukan pengalihan daripada Anda dijamin akan terhindar dari masalah.

3>File1.txt ( 4>File2.txt call :sub)
exit /b

:sub
etc.
dbenham
sumber
2
Suka solusi di mana saya dapat mengaturnya untuk sisa file
Sam
3
Perhatikan bahwa solusi panggilan mengubah % 0 Anda (menjadi sub dalam kasus ini) yang mungkin atau mungkin bukan yang Anda inginkan.
Jannes
1
@Jannes - Benar, tetapi Anda selalu bisa mendapatkan info tentang skrip batch yang sedang berjalan jika Anda menambahkan pengubah. Misalnya, %~f0selalu memberikan jalur lengkap ke skrip batch, bahkan saat berada di dalam subrutin CALLed :.
dbenham
3
@ThariqNugrohotomo ->output.txt 2>&1
dbenham
2
@Moondra - itu adalah sintaks batch standar untuk memanggil subrutin berlabel dalam skrip yang sama. Jalankan cmd /?atau help cmddari baris perintah konsol untuk dokumentasi. Trik dari metode ketiga adalah bahwa pengalihan pada CALL berlaku untuk semua perintah dalam subrutin CALL.
dbenham
66

jika Anda ingin aliran keluar dan aliran yang salah dialihkan

dir >> a.txt 2>&1
Kalpesh Soni
sumber
27
+1. Perlu juga ditunjukkan bahwa penggunaan >>akan ditambahkan ke a.txt. Untuk menimpa a.txt, gunakan >. stackoverflow.com/q/4458231/1098302
Aaron
Hai, apakah ada cara untuk mengarahkan keluaran pada konsol juga?
Sandeep Singh
itulah yang dilakukannya
Kalpesh Soni
16

Saya tahu ini adalah posting yang lebih lama, tetapi seseorang akan menemukannya di pencarian Google dan sepertinya beberapa pertanyaan yang diajukan OP dalam komentar tidak ditangani secara khusus. Juga, mohon tenanglah karena ini adalah jawaban pertama saya yang diposting di SO. :)

Untuk mengarahkan output ke file menggunakan nama file yang dibuat secara dinamis, pendekatan masuk saya (baca: cepat & kotor) adalah solusi kedua yang ditawarkan oleh @dbenham. Jadi contohnya, ini:

@echo off
> filename_prefix-%DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.log (
echo Your Name Here
echo Beginning Date/Time: %DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.log
REM do some stuff here
echo Your Name Here
echo Ending Date/Time: %DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.log
)

Akan membuat file seperti yang Anda lihat di tangkapan layar ini dari file di direktori target

Itu akan berisi keluaran ini:

Your Name Here
Beginning Date/Time: 2016-09-16_141048.log
Your Name Here
Ending Date/Time: 2016-09-16_141048.log

Juga perlu diingat bahwa solusi ini bergantung pada lokal, jadi berhati-hatilah bagaimana / kapan Anda menggunakannya.

Anthony
sumber
Terima kasih ini bermanfaat. Pertanyaan singkat apakah ada alasan mengapa Anda menggunakan .log vs .txt? Apakah itu membuat perbedaan?
Moondra
1
@Oondra tidak tidak. Ini hanya semantik dalam kasus ini. Itu tidak berarti tidak ada aplikasi yang membutuhkan / grep berdasarkan jenis file, jadi berhati-hatilah jika / bagaimana file Anda digunakan.
Anthony
9
echo some output >"your logfile"

atau

(
 echo some output
 echo more output
)>"Your logfile"

harus mengisi tagihan.

Jika Anda ingin APPENDoutput, menggunakan >>bukan >. >akan memulai logfile baru.

Magoo
sumber
9
@echo off
>output.txt (
echo Checking your system infor, Please wating...

systeminfo | findstr /c:"Host Name" 
systeminfo | findstr /c:"Domain"

ipconfig /all | find "Physical Address" 

ipconfig | find "IPv4" 
ipconfig | find "Default Gateway"

)

@pause
saif
sumber
Menurut saya ini cara yang paling elegan. Terima kasih Wesley!
Kiswanij
5

Ada program kecil keren yang dapat Anda gunakan untuk mengarahkan output ke file dan konsol

some_command  ^|  TEE.BAT  [ -a ]  filename 

AquaAlex
sumber
4

Tambahkan dua baris ini di dekat bagian atas file batch Anda, semua stdout dan stderr setelahnya akan diarahkan ke log.txt:

if not "%1"=="STDOUT_TO_FILE"  %0 STDOUT_TO_FILE %*  >log.txt 2>&1
shift /1
ilgitano
sumber
Ini berhasil untuk saya, terima kasih. Ada pertimbangan khusus yang mungkin gagal? (mis. luapan ukuran keluaran)
CCarlos
Hai, terima kasih atas jawaban Anda! apakah ada cara untuk mengarahkannya di konsol juga?
Sandeep Singh
3
@echo OFF
[your command] >> [Your log file name].txt

Saya menggunakan perintah di atas dalam file batch saya dan berhasil. Di file log, ini menunjukkan hasil dari perintah saya.

Indra Permana
sumber
0

Ini mungkin gagal dalam kasus karakter "beracun" dalam masukan. Mempertimbangkan masukan seperti iniIsAnIn ^^^^ adalah cara yang baik untuk memahami apa yang sedang terjadi. Tentu ada aturan bahwa string input HARUS berada di dalam tanda kutip ganda tetapi saya merasa bahwa aturan ini adalah aturan yang valid hanya jika arti inputnya adalah lokasi di partisi NTFS (mungkin itu adalah aturan untuk URL I saya tidak yakin). Tetapi tentu saja ini bukan aturan untuk string masukan yang berubah-ubah (ini adalah "praktik yang baik" tetapi Anda tidak dapat menghitungnya).

jan antonin
sumber
0

Menambahkan baris berikut di bagian bawah file batch Anda akan mengambil semuanya seperti yang ditampilkan di dalam jendela CMD dan mengekspor ke file teks:

powershell -c "$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys('^a')
powershell -c "$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys('^c')
powershell Get-Clipboard > MyLog.txt

Ini pada dasarnya melakukan pilih semua -> salin ke clipboard -> tempel ke file teks .

GioVi
sumber