หมายเหตุ: ต่อไปนี้จะนำไปใช้กับWindows PowerShell
ดูส่วนถัดไปสำหรับข้ามแพลตฟอร์มPowerShell หลัก (v6 +)ฉบับ
บนPSv5.1 ขึ้นไปโดยที่>
และ>>
เป็นนามแฝงที่มีประสิทธิภาพOut-File
คุณสามารถตั้งค่าการเข้ารหัสเริ่มต้นสำหรับ>
/ >>
/ Out-File
ผ่าน$PSDefaultParameterValues
ตัวแปรการกำหนดลักษณะ :
$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'
เมื่อวันที่PSv5.0 หรือต่ำกว่าคุณไม่สามารถเปลี่ยนการเข้ารหัสสำหรับ>
/>>
แต่ในPSv3 หรือสูงกว่าเทคนิคดังกล่าวข้างต้นไม่Out-File
ทำงานสำหรับการโทรที่ชัดเจนในการ
( $PSDefaultParameterValues
ตัวแปรการตั้งค่าถูกนำมาใช้ใน PSv3.0)
เมื่อวันที่PSv3.0 หรือสูงกว่าถ้าคุณต้องการที่จะตั้งค่าเริ่มต้นการเข้ารหัสสำหรับทุก cmdlets ที่สนับสนุนพารามิเตอร์
-Encoding
(ซึ่งใน PSv5.1 + รวม>
และ>>
) ใช้:
$PSDefaultParameterValues['*:Encoding'] = 'utf8'
ถ้าคุณวางคำสั่งนี้ในของคุณ$PROFILE
, cmdlets ดังกล่าวเป็นOut-File
และSet-Content
จะใช้เข้ารหัส UTF-8 โดยเริ่มต้น แต่ทราบว่านี้จะทำให้การตั้งค่าเซสชั่นระดับโลกที่จะส่งผลกระทบต่อคำสั่งทั้งหมด / สคริปที่ไม่ได้ระบุอย่างชัดเจนการเข้ารหัส
ในทำนองเดียวกันอย่าลืมรวมคำสั่งดังกล่าวไว้ในสคริปต์หรือโมดูลของคุณที่คุณต้องการทำงานในลักษณะเดียวกันเพื่อให้ทำงานเหมือนเดิมแม้ว่าจะเรียกใช้โดยผู้ใช้รายอื่นหรือเครื่องอื่นก็ตาม
ข้อแม้ : PowerShell ตั้งแต่ v5.1 สร้างไฟล์ UTF-8 อย่างสม่ำเสมอ _ ด้วย BOM_ (หลอก)ซึ่งเป็นเรื่องปกติในโลกของWindowsเท่านั้น- ยูทิลิตี้ที่ใช้Unixไม่รู้จัก BOM นี้ (ดูด้านล่าง) ดูโพสต์นี้สำหรับวิธีแก้ปัญหาที่สร้างไฟล์ UTF-8 ที่ไม่ใช้ BOM
สำหรับข้อมูลสรุปของพฤติกรรมการเข้ารหัสอักขระเริ่มต้นที่ไม่สอดคล้องกันอย่างสิ้นเชิงใน cmdlet มาตรฐานของ Windows PowerShell หลายรายการโปรดดูส่วนด้านล่าง
$OutputEncoding
ตัวแปรอัตโนมัติไม่เกี่ยวข้องกันและใช้เฉพาะกับวิธีที่ PowerShell สื่อสารกับโปรแกรมภายนอก (สิ่งที่การเข้ารหัส PowerShell ใช้เมื่อส่งสตริงไปยังพวกเขา) - ไม่มีส่วนเกี่ยวข้องกับการเข้ารหัสที่ตัวดำเนินการเปลี่ยนทิศทางเอาต์พุตและ cmdlets ของ PowerShell ใช้เพื่อบันทึกลงในไฟล์
การอ่านเพิ่มเติม: มุมมองข้ามแพลตฟอร์ม: PowerShell Core :
ขณะนี้ PowerShell เป็นแบบข้ามแพลตฟอร์มผ่านรุ่นPowerShell Coreซึ่งการเข้ารหัส - มีเหตุผล - มีค่าเริ่มต้นเป็นUTF-8 ที่ไม่ใช้ BOMซึ่งสอดคล้องกับแพลตฟอร์มที่คล้ายกับ Unix
ซึ่งหมายความว่าไฟล์ซอร์สโค้ดที่ไม่มี BOM จะถือว่าเป็น UTF-8 และใช้>
/ Out-File
/ Set-Content
ดีฟอลต์เป็นUTF-8 ที่ไม่มีBOM การใช้utf8
-Encoding
อาร์กิวเมนต์อย่างชัดเจนจะสร้างUTF-8 ที่ไม่ใช้ BOMด้วยเช่นกันแต่คุณสามารถเลือกที่จะสร้างไฟล์ด้วย pseudo-BOM ที่มีutf8bom
ค่า
หากคุณสร้างสคริปต์ PowerShell ด้วยตัวแก้ไขบนแพลตฟอร์มที่เหมือน Unix และในปัจจุบันแม้แต่บนWindows ที่มีโปรแกรมแก้ไขข้ามแพลตฟอร์มเช่น Visual Studio Code และ Sublime Text *.ps1
ไฟล์ที่ได้มักจะไม่มี UTF-8 pseudo-BOM:
- นี้ทำงานได้ดีบน PowerShell หลัก
- มันอาจพังในWindows PowerShellถ้าไฟล์มีอักขระที่ไม่ใช่ ASCII ถ้าคุณไม่จำเป็นต้องใช้อักขระที่ไม่ใช่ ASCII ในสคริปต์ของคุณบันทึกเป็น UTF-8 กับ BOM
หากไม่มี BOM Windows PowerShell (mis) จะตีความสคริปต์ของคุณว่าถูกเข้ารหัสในโค้ดหน้า "ANSI" แบบเดิม (กำหนดโดยระบบโลแคลสำหรับแอปพลิเคชันก่อน Unicode เช่น Windows-1252 ในระบบ US-English)
ตรงกันข้ามแฟ้มที่ทำมี UTF-8 หลอก BOM อาจเป็นปัญหาบน Unix-เช่นแพลตฟอร์มเช่นที่พวกเขาก่อให้เกิดสาธารณูปโภคยูนิกซ์เช่นcat
, sed
และawk
- และแม้กระทั่งบางบรรณาธิการเช่นgedit
- เพื่อผ่านการหลอก BOM ผ่านคือ ที่จะรักษามันเป็นข้อมูล
- สิ่งนี้อาจไม่ใช่ปัญหาเสมอไป แต่อาจเป็นได้อย่างแน่นอนเช่นเมื่อคุณพยายามอ่านไฟล์ในสตริง
bash
ด้วยพูดtext=$(cat file)
หรือtext=$(<file)
- ตัวแปรผลลัพธ์จะมี pseudo-BOM เป็น 3 ไบต์แรก
พฤติกรรมการเข้ารหัสเริ่มต้นที่ไม่สอดคล้องกันในWindows PowerShell :
น่าเสียใจที่การเข้ารหัสอักขระเริ่มต้นที่ใช้ใน Windows PowerShell ไม่สอดคล้องกันอย่างมาก PowerShell Coreรุ่นข้ามแพลตฟอร์มตามที่กล่าวไว้ในหัวข้อก่อนหน้านี้ได้ยุติสิ่งนี้อย่างน่ายกย่อง
บันทึก:
สิ่งต่อไปนี้ไม่ต้องการให้ครอบคลุมcmdlet มาตรฐานทั้งหมด
Googling ชื่อ cmdlet เพื่อค้นหาหัวข้อวิธีใช้ตอนนี้จะแสดงหัวข้อ PowerShell Coreให้คุณเป็นค่าเริ่มต้น ใช้รายการแบบหล่นลงของเวอร์ชันเหนือรายการหัวข้อทางด้านซ้ายเพื่อเปลี่ยนเป็นเวอร์ชันWindows PowerShell
ขณะที่เขียนนี้เอกสารไม่ถูกต้องบ่อยอ้าง ASCII ที่เข้ารหัสเริ่มต้นใน Windows PowerShell - เห็นปัญหานี้เอกสาร GitHub
Cmdlets ที่เขียน :
Out-File
และ>
/ >>
สร้าง "Unicode" - UTF-16LE - ไฟล์โดยค่าเริ่มต้นซึ่งทุกอักขระช่วง ASCII (เกินไป) จะแสดงด้วย2ไบต์ซึ่งแตกต่างจากSet-Content
/ Add-Content
(ดูจุดถัดไป) New-ModuleManifest
และExport-CliXml
ยังสร้างไฟล์ UTF-16LE
Set-Content
(และAdd-Content
ถ้าไฟล์ยังไม่มี / ว่างเปล่า) ใช้การเข้ารหัส ANSI (การเข้ารหัสที่ระบุโดยเพจรหัสเดิม ANSI ของโลแคลระบบที่ใช้งานอยู่ซึ่ง PowerShell เรียกDefault
)
Export-Csv
สร้างไฟล์ ASCII ตามที่บันทึกไว้ แต่ดูหมายเหตุ-Append
ด้านล่าง
Export-PSSession
สร้างไฟล์ UTF-8 ด้วย BOM โดยค่าเริ่มต้น
New-Item -Type File -Value
ปัจจุบันสร้าง BOM-less (!) UTF-8
Send-MailMessage
หัวข้อความช่วยเหลือยังอ้างการเข้ารหัส ASCII ที่เป็นค่าเริ่มต้น - ฉันยังไม่ได้ยืนยันเองว่าการเรียกร้อง
Start-Transcript
สร้างไฟล์ UTF-8 ด้วย BOM อย่างสม่ำเสมอแต่ดูหมายเหตุ-Append
ด้านล่าง
คำสั่ง Re ที่ต่อท้ายไฟล์ที่มีอยู่:
>>
/ Out-File -Append
ทำให้ไม่มีความพยายามที่จะตรงกับการเข้ารหัสของไฟล์ที่เนื้อหาที่มีอยู่ นั่นคือพวกเขาใช้การเข้ารหัสเริ่มต้นแบบสุ่มสี่สุ่มห้าเว้นแต่จะได้รับคำแนะนำเป็นอย่างอื่นด้วย-Encoding
ซึ่งไม่ใช่ตัวเลือกสำหรับ>>
(ยกเว้นทางอ้อมใน PSv5.1 + ผ่าน$PSDefaultParameterValues
ตามที่แสดงด้านบน) กล่าวโดยย่อ: คุณต้องทราบการเข้ารหัสเนื้อหาของไฟล์ที่มีอยู่และต่อท้ายโดยใช้การเข้ารหัสเดียวกันนั้น
Add-Content
เป็นข้อยกเว้นที่น่ายกย่อง: ในกรณีที่ไม่มี-Encoding
อาร์กิวเมนต์ที่ชัดเจนจะตรวจพบการเข้ารหัสที่มีอยู่และนำไปใช้กับเนื้อหาใหม่โดยอัตโนมัติ ขอบคุณ js2010 โปรดทราบว่าใน Windows PowerShell หมายความว่าเป็นการเข้ารหัส ANSI ที่ใช้หากเนื้อหาที่มีอยู่ไม่มี BOM ในขณะที่ UTF-8 ใน PowerShell Core
ความไม่ลงรอยกันระหว่างนี้Out-File -Append
/ >>
และAdd-Content
ซึ่งยังมีผลต่อ PowerShell หลักจะมีการหารือในประเด็น GitHub นี้
Export-Csv -Append
บางส่วนตรงกับการเข้ารหัสที่มีอยู่: มันต่อท้ายUTF-8 แบบสุ่มหากการเข้ารหัสของไฟล์ที่มีอยู่เป็น ASCII / UTF-8 / ANSI ใด ๆ แต่ตรงกับ UTF-16LE และ UTF-16BE อย่างถูกต้อง
หากต้องการทำให้แตกต่างกัน: ในกรณีที่ไม่มี BOM ให้Export-Csv -Append
ถือว่า UTF-8 คือในขณะที่Add-Content
สมมติว่า ANSI
Start-Transcript -Append
บางส่วนตรงกับการเข้ารหัสที่มีอยู่: ตรงกับการเข้ารหัสกับ BOMอย่างถูกต้องแต่ค่าเริ่มต้นคือการเข้ารหัส ASCII ที่อาจสูญเสียในกรณีที่ไม่มีการเข้ารหัส
Cmdlets ที่อ่าน (นั่นคือการเข้ารหัสที่ใช้ในกรณีที่ไม่มี BOM ):
Get-Content
และImport-PowerShellDataFile
เริ่มต้นเป็น ANSI ( Default
) ซึ่งสอดคล้องกับSet-Content
.
ANSI ยังเป็นสิ่งที่เอ็นจิ้น PowerShell เองเริ่มต้นเมื่ออ่านซอร์สโค้ดจากไฟล์
ในทางตรงกันข้ามImport-Csv
, Import-CliXml
และSelect-String
ถือว่า UTF-8 ในกรณีที่ไม่มี BOM ที่