Powershell: Apakah sudah waktunya untuk "PowerShell vZeroTechnicalDebt" dan / atau untuk mekanisme keikutsertaan ke dalam fitur baru / tetap yang merusak kompatibilitas ke belakang?

Dibuat pada 26 Apr 2018  ·  69Komentar  ·  Sumber: PowerShell/PowerShell

Perhatikan bahwa istilah _hutang teknis_ digunakan secara longgar di sini yang berarti "akumulasi perilaku rusak yang tidak dapat diperbaiki tanpa merusak kompatibilitas ke belakang";


_Update_: @rjmholt secara resmi memulai diskusi tentang cara menerapkan dan mengelola perubahan yang melanggar: # 13129.


Catatan: Masalah ini, yang muncul dari https://github.com/PowerShell/PowerShell/issues/5551#issuecomment -380522712, hanya untuk memulai diskusi untuk melihat apakah ada kemauan mendasar untuk menerima perubahan tersebut . Akhirnya, RFC dibutuhkan.

Komitmen kuat PowerShell untuk kompatibilitas ke belakang telah melayani komunitas dengan sangat baik selama bertahun-tahun.

Di sisi lain, produk sampingan yang tak terhindarkan adalah akumulasi hutang teknis yang membutuhkan mengingat pengecualian dan merupakan penghalang bagi pendatang baru.

Masalah mendasar tertentu yang ada saat ini hanya dapat diselesaikan dengan mengorbankan kompatibilitas ke belakang, dan ada dua cara - tidak saling eksklusif - untuk mengatasinya:

  • Implementasi edisi "PowerShell vZeroTechnicalDebt" yang melepaskan semua hutang teknis, tetapi kehilangan kompatibilitas mundur (mungkin dengan versi mendatang yang menggunakan versi semantik untuk menunjukkan kompatibilitas)

  • Integrasi fitur / perbaikan pemecah kompatibilitas mundur ke dalam basis kode yang ada, hanya tersedia secara ketat pada basis _opt-in_.

Pendekatan mana, jika ada, yang ingin kita pertimbangkan?
Setelah kami memiliki kejelasan tentang itu, kami dapat menyempurnakan prosesnya.

Berikut adalah beberapa masalah mendasar yang ada yang hanya dapat diselesaikan dengan mengorbankan kompatibilitas ke belakang; Saya yakin orang lain akan memikirkan lebih banyak:

Data lingkungan

Ditulis pada:

PowerShell Core v6.0.2
Issue-Meta

Komentar yang paling membantu

Ada mahal untuk memperbaiki masalah yang saya anggap sebagai hutang teknis PowerShell yang tidak mengadopsi konsep .NET baru saat muncul

  • Sintaks bahasa untuk parameter tipe untuk metode generik # 5146

  • Dukungan mesin untuk Extension Methods muncul secara otomatis dalam sistem tipe (seperti yang mereka lakukan dalam bahasa _compiled_ .Net). # 2226

  • Dukungan bahasa untuk async API # 6716 (dan RFC )

Ada beberapa fitur yang disesalkan:

  • Bisakah kita melakukan sesuatu berdasarkan petunjuk tipe (seperti @KirkMunro 's FormatPx ) daripada cmdlet yang menampilkan objek pemformatan? # 4594 # 4237 # 3886

  • Apakah Anda akan menormalkan penyedia Registri menjadi berbasis _content_ - alih-alih merasa seperti demo tentang cara kerja penyedia properti? # 5444

  • Apakah Anda akan melakukan refactor PSProviders secara mendalam untuk membuatnya lebih mudah untuk ditulis? Sayang sekali dibutuhkan dua lapisan abstraksi untuk sampai di "SHiPS" dan akhirnya memberi orang cara untuk menulis penyedia yang ingin mereka gunakan

Bagaimana dengan pertanyaan yang lebih besar:

Apakah kita bersedia untuk mempertimbangkan kembali pendekatan "banyak cara lebih baik" dan mengerjakan pendekatan "lubang kesuksesan"? Maksud saya, apakah kita bersedia menghapus fitur yang dianggap "cara mudah" tetapi yang secara fundamental lebih buruk, demi hanya memiliki "cara yang benar" untuk melakukan sesuatu? Misalnya:

  • Buat CmdletBinding selalu aktif
  • Membuat notasi @ () berarti List[PSObject]
  • Hasilkan @ {} berarti Dictionary[PSObject, PSObject] (atau Dictionary[string, PSObject] 😲)
  • Jadikan _Process_ sebagai blok default
  • Bahkan mungkin menjadikan _ValueFromPipelineByPropertyName_ sebagai default ;-)

Semua 69 komentar

Menarik. Saya selalu bertanya-tanya mengapa 1 di .ps1 akan digunakan untuk menambahkan semacam versi semantik ke skrip PowerShell, memungkinkan skrip untuk menunjukkan apakah itu disesuaikan dengan kemungkinan perubahan yang merusak.

Ada mahal untuk memperbaiki masalah yang saya anggap sebagai hutang teknis PowerShell yang tidak mengadopsi konsep .NET baru saat muncul

  • Sintaks bahasa untuk parameter tipe untuk metode generik # 5146

  • Dukungan mesin untuk Extension Methods muncul secara otomatis dalam sistem tipe (seperti yang mereka lakukan dalam bahasa _compiled_ .Net). # 2226

  • Dukungan bahasa untuk async API # 6716 (dan RFC )

Ada beberapa fitur yang disesalkan:

  • Bisakah kita melakukan sesuatu berdasarkan petunjuk tipe (seperti @KirkMunro 's FormatPx ) daripada cmdlet yang menampilkan objek pemformatan? # 4594 # 4237 # 3886

  • Apakah Anda akan menormalkan penyedia Registri menjadi berbasis _content_ - alih-alih merasa seperti demo tentang cara kerja penyedia properti? # 5444

  • Apakah Anda akan melakukan refactor PSProviders secara mendalam untuk membuatnya lebih mudah untuk ditulis? Sayang sekali dibutuhkan dua lapisan abstraksi untuk sampai di "SHiPS" dan akhirnya memberi orang cara untuk menulis penyedia yang ingin mereka gunakan

Bagaimana dengan pertanyaan yang lebih besar:

Apakah kita bersedia untuk mempertimbangkan kembali pendekatan "banyak cara lebih baik" dan mengerjakan pendekatan "lubang kesuksesan"? Maksud saya, apakah kita bersedia menghapus fitur yang dianggap "cara mudah" tetapi yang secara fundamental lebih buruk, demi hanya memiliki "cara yang benar" untuk melakukan sesuatu? Misalnya:

  • Buat CmdletBinding selalu aktif
  • Membuat notasi @ () berarti List[PSObject]
  • Hasilkan @ {} berarti Dictionary[PSObject, PSObject] (atau Dictionary[string, PSObject] 😲)
  • Jadikan _Process_ sebagai blok default
  • Bahkan mungkin menjadikan _ValueFromPipelineByPropertyName_ sebagai default ;-)

Semua saran bagus, @Jaykul.

Membuat kembali @() notasi berarti List[PSObject] : Saya pikir kita dapat mengambil ini lebih jauh dan menggunakan jenis koleksi yang dapat diperluas secara efisien sebagai jenis koleksi dasar PowerShell, sehingga digunakan dimanapun [object[]] saat ini adalah (dan digunakan secara internal serta saat mengembalikan koleksi, tanpa penalti kinerja konversi jenis); ada tantangan sekitar + use, tetapi @PetSerAl telah menyarankan implementasi daftar kustom untuk mengatasinya .

Membuat kembali Process {} blok default dalam fungsi, sebagai tambahan: itulah yang saat ini dilakukan Filter , tetapi terbatas pada blok - tersirat - Process , dan varian fungsi ini tampaknya tidak pernah benar-benar populer; menyatukan keduanya dalam konteks Function masuk akal bagi saya.

Lucu, pada panggilan siaga komunitas Azure PowerShell sekarang, dan mereka akan berpindah dari AzureRm ke modul Az baru yang lintas platform (tidak ada AzureRm.Core terpisah), dan dengan semua awalan perintah diubah dari AzureRm ke Az. Keduanya akan berdampingan untuk sementara waktu, tetapi mereka berpindah ke set perintah baru.

Sayang sekali PowerShell belum memiliki kesempatan untuk membuat executable baru yang akan berjalan berdampingan dengan Windows PowerShell, tetapi itu bisa melepaskan diri dari beberapa warisan lama yang menyeretnya ke bawah.

Bayangkan saja apa yang akan terjadi jika kita melakukannya:
Secara realistis, dibutuhkan setidaknya 6 bulan upaya terfokus untuk menghasilkan versi 'tanpa penyesalan' dan 6 bulan lagi untuk mengulanginya. Kemudian modul pihak ke-3 perlu beradaptasi dengannya juga agar versi ini berguna, yang akan membutuhkan setidaknya 6 bulan lagi untuk mendapatkan cakupan yang wajar (dan perlu diingat bahwa beberapa modul tidak akan pernah) ... penundaan dan masalah tak terduga, dll ... Jadi, tidak, saya pikir itu hanya angan-angan bahwa seseorang dapat menyingkirkan semua hutang teknis dalam satu versi sekaligus (dan masih mengembangkan dan tidak hanya mempertahankan versi lama).

Sebanyak saya berharap versi seperti itu ada, saya pikir itu hanya akan mungkin untuk mendapatkannya perlahan-lahan satu perubahan besar pada satu waktu. Dengan v6 banyak perubahan yang melanggar sudah diterima tetapi saya pikir jika seseorang menyertakan terlalu banyak perubahan yang melanggar dalam satu versi, itu akan menjadi terlalu rumit untuk meningkatkan skrip / modul yang ada. Ada baiknya untuk membahas perubahan pemutusan yang paling berharga tetapi sampai tidak ada versi LTS dari pwsh, saya rasa belum waktunya untuk memikirkan tentang memiliki rangkaian pwsh ke-2 dengan perubahan yang lebih substansial secara paralel dengan versi arus utama yang ada.

@bergmeister Setuju. Namun, bahkan perubahan yang relatif kecil pada jalur inti dapat sangat menghambat adopsi. Lihatlah Python 3. Butuh 10 _years_ untuk benar-benar mengerti. Dengan perubahan yang jauh lebih besar, siapa yang tahu berapa lama waktu yang dibutuhkan Perl 6 untuk menjadi dominan (dan mereka membutuhkan waktu 15 tahun untuk menghasilkan hal yang benar sehingga 1,5 tahun untuk PowerShell ++ tampak optimis :-)) Di sisi lain PHP tampaknya merusak barang-barang secara teratur, mungkin karena cara dan kegunaannya.

Python 3 tentu saja merupakan pertunjukan horor, apakah sudah populer? Saya masih menjalankan 2.7, dan tidak berencana untuk mengupgrade dalam waktu dekat. Tapi saya juga belum mendengar banyak tentang Perl 6 ...

Saya pikir pelajaran yang harus dipelajari dari Python ada untuk memisahkan perubahan yang melanggar bahasa dari perubahan versi ke mesin. Secara hipotetis, mesin PS 7 masih dapat menjalankan file skrip sebelumnya (.PS1) dalam mode perubahan tanpa gangguan, sementara jika skrip ditandai sebagai 7 sadar (katakanlah dengan ekstensi .PS7) mereka dapat menyatakan bahwa mereka telah diperbarui _dan_ membutuhkan setidaknya PS 7 untuk dijalankan. Harapan itu masuk akal.

Mungkin kisah sukses terbaik adalah JavaScript / TypeScript / Babel. Transpiler (dengan dukungan peta sumber) sepertinya merupakan cara yang tepat untuk evolusi bahasa.

Javascript adalah kasus khusus. Anda cukup terjebak dengan itu sehingga transpiling benar-benar satu-satunya pilihan. Ketikan adalah "hanya" Javascript dengan ekstensi sehingga mudah bagi orang untuk mengadopsi. Setiap program javascript adalah program ketikan sehingga Anda memulai dengan apa yang Anda miliki dan menambahkan penjelasan dari sana. Dart, di sisi lain, adalah bahasa itu sendiri tetapi transparan ke javascript atau runtime asli di Chrome (setidaknya itulah rencananya pada satu titik). Dart tampaknya tidak mendapatkan banyak adopsi di luar Google, kemungkinan karena itu adalah bahasanya sendiri ..

@Tokopedia

Python 3 tentu saja merupakan pertunjukan horor, apakah sudah populer?

Saya membaca artikel minggu lalu di mana penulis mengklaim masa kritis telah dicapai untuk Python 3. Bahwa semua modul inti tersedia dan sekarang orang-orang yang bermigrasi berbondong-bondong. Kita akan melihat..

Menarik. Saya selalu bertanya-tanya mengapa 1 dalam .ps1 akan digunakan untuk menambahkan semacam versi semantik ke skrip PowerShell, memungkinkan skrip untuk menunjukkan apakah itu disesuaikan dengan kemungkinan perubahan yang merusak ..

WRT .ps1 , kami berhak mengubah ekstensi jika bahasa kami salah total yang mengakibatkan perubahan besar pada runtime sehingga skrip untuk versi sebelumnya tidak berfungsi. Tetapi mengubah perluasan juga mengarah pada tumpukan pekerjaan yang sangat besar karena begitu banyak hal dalam ekosistem terkait dengan perluasan. Jadi itu bukan sesuatu yang bisa dilakukan dengan mudah. Dan tentu saja, menjadi bagian dari Windows, jika kita mem-fork ekstensinya, kita masih harus mempertahankan kedua versi (seperti Python 2/3).

@gambarunik :

Masalah yang valid, tetapi dalam semangat:

Sebaiknya diskusikan perubahan yang paling berharga

tolong bagikan apa pun yang mungkin Anda pikirkan.

perlahan-lahan satu per satu perubahan

Meskipun mekanisme keikutsertaan (cakupan leksikal) untuk perubahan yang tidak kompatibel adalah solusinya, saya khawatir tentang dua hal:

  • Pengenalan sedikit demi sedikit dapat menyebabkan tidak ada yang bisa mengingat versi mana yang diperlukan untuk fitur apa; Perl (v5-) muncul di benak Anda.

  • Basis kode menjadi membengkak dan sulit untuk dipertahankan, dan biner yang dihasilkan juga membengkak, yang melukai (setidaknya) kinerja startup.

Saya sudah mengatakannya sebelumnya: bagi saya - dan ini hanya firasat - v6 GA adalah kompromi yang tidak menguntungkan antara membuat orang-orang lama tidak senang dengan perubahan yang melanggar sementara membawa cukup bagasi untuk menghalangi adopsi Di dunia [-seperti] Unix.

Yang mengatakan, mengingat relatif muda PowerShell di dunia [-like] Unix, mungkin ada (masih) lebih dari kemauan untuk menyelesaikan masalah melalui perubahan yang tidak kompatibel. Seperti yang dinyatakan @BrucePay , Windows PowerShell tetap harus dipertahankan, dan tetap menjadi tempat berlindung yang aman untuk kompatibilitas ke belakang.

Saya pikir skala konsekuensi negatif dari perubahan yang merusak tersebut telah tercakup, dan saya setuju dengan sebagian besar poin tersebut. Saya menulis ini karena saya ragu bahwa, dalam konteks yang lebih besar, perubahan ini akan menghasilkan manfaat yang signifikan pada awalnya. Setidaknya untuk cara saya menggunakan PowerShell.

OP mencakup pernyataan berikut:

Di sisi lain, produk sampingan yang tak terhindarkan adalah akumulasi hutang teknis yang membutuhkan mengingat pengecualian dan merupakan penghalang bagi pendatang baru.

Premis tersirat dari pernyataan ini tampaknya adalah bahwa membuat berbagai perubahan yang merusak ini akan meringankan beban mengingat pengecualian. Memang itu akan menjadi hasil yang bagus. Namun, saya skeptis bahwa itulah hasilnya. Perilaku PowerShell sengaja kaya. Ini membuatnya ekspresif dan tidak dapat diprediksi. Ekspresi dan prediktabilitas tampaknya bekerja berlawanan satu sama lain, setidaknya di antara bahasa yang saya kenal.

Meskipun saya setuju bahwa banyak perubahan yang melanggar yang disebutkan di atas akan meningkatkan prediktabilitas dalam beberapa kasus, banyak aspek bahasa yang tidak dapat diprediksi dan mengejutkan akan tetap ada. Meskipun menghabiskan waktu bertahun-tahun menulis PowerShell, saya masih sering terkejut dengan perilaku PowerShell yang tampaknya sesuai desain dan mungkin tidak boleh diubah. Beberapa contoh terbaru yang muncul di benak adalah sebagai berikut:

  • pengikatan tertunda bersyarat dari [scriptblock] argumen (# 6419)
  • kapan tepatnya, pencacahan implisit terjadi (# 5832)
  • konversi [AutomationNull]::Value menjadi $null selama pengikatan parameter (# 6357 terkait)
  • dampak dari break dan continue pada aliran kontrol dalam pipa (# 5811)
  • apa yang terjadi jika Anda memerciki $null ( SO )
  • bagaimana penggunaan scriptblock di seluruh status sesi memengaruhi $_ ( SO 1 , SO 2 )

Saya berharap bahwa contoh-contoh ini hanyalah sebagian kecil dari banyak nuansa lain yang dirancang dengan cermat namun mengejutkan yang belum saya temukan. Saya memilih contoh ini karena

  1. mereka mewakili perilaku yang mungkin tidak dapat ditingkatkan di PowerShell, dan
  2. Saya tidak memiliki harapan untuk secara andal melihat semua implikasinya saat membaca atau menulis PowerShell.

Saya baik-baik saja dengan ini. Sebagian besar perilaku PowerShell yang mengejutkan tidak berdampak lama pada kesuksesan saya dengan PowerShell. Perilaku mengejutkan hampir selalu tertangkap langsung oleh pengujian selama pengembangan. Saya belajar dari hal-hal yang lolos dan menggunakannya untuk meningkatkan strategi pengujian saya. Ini benar apakah perilaku mengejutkan itu adalah jenis yang bisa dihilangkan atau jenis yang harus tetap ada.

Apakah perubahan yang diusulkan di atas dibuat atau tidak, PowerShell tidak akan pernah begitu dapat diprediksi sehingga saya dapat mengurangi cakupan pengujian secara signifikan. Dengan kata lain, cara saya menggunakan PowerShell, menurut saya tidak ada banyak keuntungan yang mungkin terjadi dengan membuat perubahan melanggar yang diusulkan di atas.

(BTW, terima kasih @ mklement0 karena langsung menanyakan pertanyaan ini. Ini sudah lama ada di benak saya. Senang melihat kesempatan bagi semua orang untuk mengatakan bagian mereka.)

Terima kasih, @ alx9r.

Saya pikir penting untuk membedakan antara kompleksitas _intrinsic_ dan kompleksitas _extrinsic_:

  • _Intrinsic_ kompleksitas berasal dari kompleksitas inheren dari konsep yang sedang diimplementasikan, yang dalam kasus PowerShell memiliki dua sumber utama: _internal_ kompleksitas dari memperkenalkan paradigma baru (pipa berbasis objek) dan menggabungkan dua dunia yang berbeda (sintaks shell dan sintaks bahasa pemrograman ), dan kompleksitas _external_ dari interaksi dengan banyak dunia luar yang berbeda.

  • Kompleksitas _Extrinsic_ berasal dari abstraksi yang bocor dan inkonsistensi.

    • Kompleksitas seperti itu harus _dihilangkan_.
    • Jika itu bukan pilihan karena masalah kompatibilitas ke belakang, kerumitan seperti itu harus _dokumentasi sebagai masalah yang diketahui_.

    • Perilaku pelingkupan variabel script-module (yang Anda rujuk dalam konteks $_ ) lebih dari sekedar quirk: ini adalah akar penyebab dari masalah utama, # 4568 yang disebutkan sebelumnya.

    • Semua masalah lain yang Anda sebutkan menurut saya termasuk dalam kategori ekstrinsik (bukan akibat desain yang cermat), karena semuanya hadir sebagai inkonsistensi yang tidak memiliki alasan atau manfaat yang jelas (didokumentasikan):

      • Lebih masuk akal untuk memerciki dengan $null untuk meneruskan argumen _no_ daripada argumen posisi $null .
      • Mengapa [System.Management.Automation.Internal.AutomationNull]::Value dikonversi menjadi $null selama _parameter binding_, meskipun jenisnya disimpan dalam _direct variable assignment_? Lihat https://github.com/PowerShell/PowerShell/issues/9150#issuecomment -473743805
      • Apa keuntungan yang ada pada cakupan _dynamic_ break dan continue , di seluruh tumpukan panggilan, dengan _quiet termination_ jika tidak ada loop penutup yang ditemukan?

Meskipun kekayaan fitur dan penggabungan dunia yang berbeda saja membuatnya sulit untuk mengingat semua kompleksitas _intrinsic_ yang diperlukan, meminimalkan _extrinsic_ tetap penting.

Harus menguji pendekatan yang Anda maksudkan terlebih dahulu tanpa hanya mengetahui dan percaya bahwa itu akan berhasil - atau membuat hal-hal tiba-tiba rusak karena perilaku yang mengejutkan - adalah hambatan produktivitas (dan kesenangan) yang serius (meskipun PowerShell secara terpuji membuatnya sangat mudah untuk menguji perilaku secara interaktif ).

Itu bermuara pada konsep solid (yang tidak bertentangan dengan ekspektasi intuitif), penamaan deskriptif, dan dokumentasi yang baik:

Jika saya tidak mengetahuinya / tidak yakin apakah saya ingat dengan benar, saya perlu tahu di mana mencarinya, dan yakin bahwa _masalah yang diketahui dan kasus edge_ juga didokumentasikan (baik sebagai bagian dari topik bantuan biasa atau melalui tautan dari sana).

Jadi, meskipun kita memutuskan bahwa _menghilangkan_ kompleksitas ekstrinsik bukanlah suatu pilihan, kita setidaknya dapat _dokumentasi secara sistematis_ - dan pembahasan di sini dapat berfungsi sebagai titik awal untuk menyusun "galeri kesalahan" (yang mungkin juga mencakup kasus kompleksitas _intrinsic_ yang tidak dapat dihindari yang mungkin mengejutkan).

setidaknya kita dapat mendokumentasikannya secara sistematis - dan diskusi di sini dapat menjadi titik awal untuk menyusun "galeri lubang"

Roman Kuzmin telah mengumpulkan galeri seperti itu untuk sementara waktu, di sini: https://github.com/nightroman/PowerShellTraps

Terima kasih, @HumanEquivalentUnit - sepertinya koleksi yang bagus.

Bersama dengan masalah yang dikumpulkan di utas ini, ini bisa menjadi dasar untuk galeri yang merupakan bagian dari dokumentasi _official_, dengan setiap entri ditambah, jika sesuai:

  • alasan desain yang menjelaskan mengapa perilaku tersebut, meskipun mungkin mengejutkan, dapat dibenarkan (penjelasan yang dibingkai dengan tepat dapat membuat elemen kejutan dapat hilang)

  • pengakuan masalah, menyatakan bahwa:

    • baik: itu tidak akan diperbaiki untuk kepentingan kompatibilitas ke belakang.
    • atau: bahwa perubahan masa depan sedang dipertimbangkan
    • atau: bahwa masalah sudah diperbaiki di PS _Core_

Aneh bahwa harus ditanya apakah sudah waktunya untuk "PowerShell vZeroTechnicalDebt" _

Tepat untuk ini ada perintah versi yang diperlukan.

Jika ada sesuatu yang rusak di versi baru, satu-satunya rasa sakit yang kita dapatkan adalah kita harus belajar dan mempelajari perbedaan kecil yang biasanya terjadi.

Tapi kami (akhirnya) mendapatkan platform, yang benar-benar menjadi lebih baik dengan setiap iterasi di intinya. Dan lebih mudah dirawat.

Tidak, tidak ada pertanyaan untuk memulai desain dan keputusan yang buruk dengan pengetahuan dan teknologi baru.

Selain itu, untuk membuang kotoran yang hidup dari kuda mati, masih sangat sulit untuk menulis fungsi atau cmdlet berperilaku baik yang berhubungan dengan perbedaan ajaib antara sistem file asli host dan filesystemprovider. Kode bernuansa seperti itu sulit untuk ditulis dan sering kali salah. Berikut adalah posting di stackoverflow yang saya jawab sekitar tujuh atau delapan tahun yang lalu yang masih valid:

https://stackoverflow.com/questions/8505294/how-do-i-deal-with-paths-when-writing-a-powershell-cmdlet

Ref: # 8495

Ada beberapa aturan prioritas operator aneh yang perlu direvisi:

PS> 1, 2, 2 + 1, 4, 4 + 1
1
2
2
1
4
4
1

Dalam kebanyakan bahasa, orang akan lebih sering mengharapkan ini menjadi keluaran:

1
2
3
4
5

Satu opsi yang memiliki pro dan kontra sendiri adalah tanda fitur baru untuk mengaktifkan semua perilaku "ideal" sehingga ikut serta. Jika kami memiliki beberapa telemetri yang menunjukkan bahwa sebagian besar penggunaan telah berpindah ke perilaku baru, kami dapat membaliknya sehingga tidak digunakan. Ini semua mungkin hanya mimpi pipa karena saya belum pernah melihat kasus dunia nyata di mana model seperti itu bekerja ...

Memang itu _nice_, tetapi mengingat sifat yang agak ... menyeluruh ... dari beberapa revisi di utas ini, ini berisiko berpotensi _splitting_ kompatibilitas skrip antara "normal" dan "eksperimental", dan berpotensi menjadi beberapa bagian, tergantung pada bendera mana yang diaktifkan oleh seseorang.

Ini berarti kami tidak dapat benar-benar mengandalkan apa pun yang merupakan fitur eksperimental dengan cara itu, atau menulis skrip dan modul yang mengandalkannya, kecuali kami melampirkan peringatan besar ke halaman dokumen, atau berpotensi mencegahnya diimpor kecuali bendera tertentu diaktifkan.

_Might_ ini dapat dihindari, namun ... jika kami dapat, sesuka hati, mengaktifkan dan menonaktifkan fitur eksperimental tertentu pada basis per-tiap-cakupan-modul. Tapi, mengingat itu hanya memperumit masalah, saya bahkan tidak yakin apakah itu solusi yang sangat bagus.

@ vexx32 hanya untuk memperjelas, saya tidak menyarankan flag experimental yang pada akhirnya akan menjadi non-eksperimental. Saya sedang memikirkan sesuatu yang berbeda (mungkin lebih seperti Enable-PSFeature karena akan didukung secara resmi (dan dengan demikian dilindungi dari perubahan yang merusak tidak seperti fitur eksperimental)). Saya juga berpikir itu akan menjadi satu bendera di mana Anda memilih untuk mengubah perubahan baru ini sebagai satu set daripada secara individual.

Oh, kalau begitu ... Ya, tentu saja. Itu akan memungkinkan kami mengemas semuanya dengan rapi di bawah satu payung, dan benar-benar menggunakannya. Jauh lebih baik dari apa yang saya pikirkan! 😄

Tambahan @ jszabo98 ke daftar masalah yang dikompilasi di sini, berdasarkan # 8512:

-and dan -or tiba-tiba memiliki prioritas _same_, sedangkan di sebagian besar bahasa (termasuk C #) -and memiliki prioritas lebih tinggi dari -or .

Contoh ekspresi yang bertentangan dengan ekspektasi:

PS> $true -or $true -and $false
False

Karena asosiasi kiri dan -and dan -or memiliki prioritas yang sama, di atas dievaluasi sebagai ($true -or $true) -and $false daripada yang diharapkan $true -or ($true -and $false)

Ini semua mungkin hanya mimpi pipa karena saya belum pernah melihat kasus dunia nyata di mana model seperti itu bekerja ...

Faktanya, kami sudah memiliki model yang berfungsi di seluruh dunia - LTS. MSFT menggunakan ini untuk mengembangkan Windows 10. Model ini digunakan untuk mengembangkan distribusi Unix.
Bagi kami, ini berarti kami dapat merilis versi LTS PowerShell Core setiap dua tahun dan memasukkannya ke dalam versi Windows 10 LTS dan versi Unix LTS. (Satu masalah adalah menyinkronkan tanggal rilis Windows dan Unix untuk versi LTS. Saya kira MSFT dapat bernegosiasi dengan perusahaan utama Unix.)
Selama dua tahun ini, kami mengumpulkan perubahan kerusakan kecil, mentransfer perubahan pemutusan yang lebih signifikan ke siklus berikutnya.
Untuk setiap versi LTS baru, ScriptAnalyzer harus mendapatkan seperangkat aturan baru untuk memfasilitasi migrasi skrip.
Dengan model ini, produk dan skrip penting hanya perlu beralih dari versi sebelumnya ke versi berikutnya setelah pengujian dan migrasi menyeluruh.

Saya menggunakan pendekatan ini ketika saya memigrasi langkah demi langkah (versi demi versi) sistem lama dari versi PHP 4 ke versi PHP berikutnya sampai saya mencapai versi PHP 5.x yang didukung. Pada setiap langkah, saya harus membuat perubahan yang relatif kecil dan cepat, setelah itu sistem terus bekerja selama beberapa waktu hingga langkah berikutnya.

Pembaruan: Ini harus disinkronkan dengan versi .Net Core LTS. Saya berharap bahwa .Net Core 3.1 akan menjadi LTS berikutnya dan PowerShell Core 6.x seharusnya ada pada versinya.

Secara jujur? Kedengarannya ide yang sangat _great_ untuk PowerShell Core. Itu akan memungkinkan kami untuk membuat perubahan besar seperti ini yang benar-benar dapat membantunya bergerak maju, tidak membebani terlalu banyak dengan masalah kompatibilitas, sementara _also_ tidak membebani dengan terlalu banyak perubahan yang melanggar sementara antara rilis LTS.

Ref: https://github.com/PowerShell/PowerShell/pull/8407#issuecomment -453221566

Get-Variable -ValueOnly -Name myVar | Should -Be $var pernyataan gagal saat $var adalah sebuah array.

Ini karena Get-Variable -ValueOnly tidak menggunakan kelebihan pencacahan untuk WriteObject() .

Mengenai memiliki beberapa versi PowerShell yang memiliki kumpulan fitur berbeda dan perubahan yang merusak: Kami sudah memiliki ini dengan warisan dan inti. Yang tampak buruk pada pandangan pertama tetapi dapat memberikan model kerja untuk masa depan. Tetap bersamaku...

Kita harus mengatur hampir semua proses yang menggunakan PowerShell untuk memanggil inti pwsh.exe sebelum menjalankan skrip yang sebenarnya karena tugas terjadwal Windows, jenkins, dan banyak lingkungan tidak sadar inti PowerHell. Kami melakukan ini karena kami menggunakan fitur yang hanya tersedia di versi PS tertentu.

Dalam kasus di mana kami tidak dapat memaksa panggilan ke inti, kami harus memiliki setiap skrip untuk memeriksa versi PS mana yang dijalankannya dan kemudian memanggil dirinya sendiri menggunakan versi PS yang sesuai pada sistem host. Trik apa pun yang kami gunakan untuk mendapatkan kode yang tepat agar berjalan di lingkungan yang tepat, kami sering kali meneruskan semua lingkungan dan parameter ke skrip yang sama yang sudah berjalan.

Itu adalah filosofi UNIX. Membuat alat melakukan satu hal dan melakukannya dengan baik. Kemudian gabungkan alat untuk membuat keseluruhan yang lebih besar dari jumlah bagiannya. Ini adalah dunia scripting tempat kami membuat panggilan subkulit ke utilitas lain sepanjang waktu dan memproses hasil. Secara historis itulah skrip. Tren Powershell ke arah konvensi aneh dengan mencoba mempertahankan semua kode asli tetapi itu hanya konvensi - bukan persyaratan. PS berjalan dengan akses ke OS dan semua utilitas tersedia seperti skrip shell unix.

Ini akan jauh lebih mudah jika ekstensi file untuk inti telah diperbarui ke .ps6 sehingga mesin PowerShell dapat melakukan pekerjaannya untuk kita. Setiap versi biner PowerShell dapat tetap independen dari yang lain selama setiap panggilan ke satu melewati lingkungan dan mengembalikan keluaran, kesalahan, peringatan, pengecualian, ke yang lain - yang harus kita lakukan secara manual sekarang dengan usaha keras. Tidak perlu memiliki flag yang kompatibel dengan versi sebelumnya di mesin selama mesin mengetahui versi mana yang harus dijalankan. Peralihan konteks yang terlibat sudah terjadi sehingga kami sudah berada di skenario kasus terburuk.

Kami akan dipaksa untuk menggunakan peretasan yang mengerikan di PowerShell selamanya KECUALI jika kami melanjutkan dan menghancurkan sesuatu dengan cara yang jelas. Menghancurkan perubahan tidak akan membuat hidup kita lebih sulit dari sebelumnya. Alternatifnya, jika kita menggunakan peningkatan berkelanjutan dan inkremental dan memiliki mesin melakukan pengangkatan yang berat dalam konteks pengalihan maka kode kita (dan kehidupan) akan menjadi lebih baik.

@ jtmoree-kahalamgmt-com Terima kasih atas tanggapan Anda! Jangan ragu untuk membuka masalah baru untuk berbagi pengalaman dan umpan balik Anda dan meminta fitur baru yang bermanfaat.

Ini akan jauh lebih mudah jika ekstensi file untuk inti telah diperbarui ke .ps6 sehingga mesin PowerShell dapat melakukan pekerjaannya untuk kita.

Lihat https://github.com/PowerShell/PowerShell/issues/2013#issuecomment -247987977

Dan saya membuat https://github.com/PowerShell/PowerShell/issues/9138 berdasarkan masukan Anda.

Python 3 tentu saja merupakan pertunjukan horor, apakah sudah populer? Saya masih menjalankan 2.7, dan tidak berencana untuk mengupgrade dalam waktu dekat. Tapi saya juga belum mendengar banyak tentang Perl 6 ...

Saya pikir pelajaran yang harus dipelajari dari Python ada untuk memisahkan perubahan yang melanggar bahasa dari perubahan versi ke mesin. Secara hipotetis, mesin PS 7 masih dapat menjalankan file skrip sebelumnya (.PS1) dalam mode perubahan tanpa gangguan, sementara jika skrip ditandai sebagai 7 sadar (katakanlah dengan ekstensi .PS7) mereka dapat menyatakan bahwa mereka telah diperbarui _dan_ membutuhkan setidaknya PS 7 untuk dijalankan. Harapan itu masuk akal.

Saya pikir menyebut Python 3 sebagai pertunjukan horor terlalu dramatis. Jika saya melihat paket unduhan teratas PyPi , dan mengambil metadata paket individu tentang unduhan v2 vs v3, saya melihat v3 sekarang telah menembus 33% penetrasi untuk hampir semua paket teratas, dan untuk perpustakaan yang lebih baru seperti perpustakaan permintaan Ken Reitz, itu hampir 50/50 terbagi: kemarin ada 685k unduhan v3, vs 875k v2.

Hal utama yang menahan Python 3 untuk waktu yang lama adalah dukungan komunitas ilmiah untuk panda dan pysci. Namun, dalam statistik terbaru, komunitas ilmiah sekarang lebih memilih Python 3 daripada Python 2: https://pypistats.org/packages/pandas unduhan 231k v3, vs unduhan 175k v2.

Seperti yang dikatakan oleh Dr. W. Edwards Deming yang terkenal, "Kami percaya kepada Tuhan; yang lainnya, bawalah data!" Mungkin Anda dapat menulis skrip PowerShell untuk menganalisis kumpulan data PyPi dan memberi tahu saya betapa mengerikan Python 3 menggunakan data: https://packaging.python.org/guides/analyzing-pypi-package-downloads/

Saya akan senang dengan (dalam urutan yang persis seperti ini):

  1. Lebih mudah menggunakan sistem modul yang menghasilkan jejak tumpukan yang baik.

    • Misalnya, file psm1 memungkinkan untuk mendeskripsikan aturan arbitrer tentang bagaimana fungsi dimuat, tetapi ini menyebabkan jejak tumpukan samar di mana semua fungsi digabung ke dalam file psm1 secara logis. Ini berarti nomor baris pada jejak tumpukan sama bermanfaatnya dengan teko cokelat.
  2. Ganti pemformatan string objek Kesalahan default PowerShell yang menelan 99% kegunaan pemrograman dalam arsitektur von Neumann berbasis tumpukan.

    • C # kurang lebih melakukan ini dengan benar. PowerShell terlalu pintar setengahnya.
  3. Perbaiki pengalihan null sehingga tiga cara berbeda untuk mengalihkan aliran output ke perangkat null memiliki performa yang setara.

  4. Perbaiki pelingkupan dinamis :

function a($f) {& $f}
function main() {
    $f = {write-host 'success'}
    a {& $f} # stack-overflow
    a {& $f}.getnewclosure() # okay
}
[void] (main)
  1. Perbaiki tangkapan variabel :
set-strictmode -version 'latest'
$erroractionpreference = 'stop'

function main() {
    $a = 'foo'
    $f = {
        $g = {$a}.getnewclosure()
        & $g # "variable '$a' cannot be retrieved because it has not been set."
    }.getnewclosure()
    & $f
}

main
  1. Output terakumulasi; return tidak melakukan hal yang sama seperti bahasa lain; memperbaikinya.

  2. PowerShell tidak memiliki gula sintaksis untuk Membuang Sumber Daya Eksternal Objek

  3. Tulis ulang PowerShellGet. Ini menyebalkan. Berfungsi dengan ratusan baris kode, pengecualian tertelan, tidak ada cakupan pengujian.

  4. Singkirkan cara kerja cache modul.

    • Cache tidak aman untuk thread. WTF?
    • Seluruh konsep caching modul untuk tujuan analisis adalah kludge / hack. Saya menyadari di dalam Microsoft ada dukungan besar untuk fitur ini karena PowerShell sangat lambat, tetapi lihat saran saya berikutnya untuk perbaikan yang sebenarnya.
    • Satu-satunya cara untuk menghapus AnalysisCache Anda adalah dengan memulai ulang PowerShell.exe
    • Caching modul untuk tujuan analisis menggabungkan analisis dengan kondisi run-time modul.
  5. Menyediakan "modul yang dikompilasi" mirip dengan bagaimana file Py dikompilasi ke file pyc untuk peningkatan kinerja.

  6. Tambahkan $none literal

    • Pertimbangkan untuk mengganti $null dengan $none di banyak tempat
    • Pertimbangkan kembali cara kerja ParameterSetName, dan izinkan meneruskan nilai khusus $none ke parameter, sehingga saya tidak perlu menulis pernyataan sakelar gila untuk memanggil kode 5 cara berbeda. COM dan C # dynamic melakukan ini dengan benar - PowerShell menjadikan ini bencana. Contohnya adalah bagaimana saya harus secara dinamis memetakan konfigurasi penerapan untuk laporan SSRS dalam modul ReportingServicesTools berdasarkan jenis Kejadian Langganan. Saya lebih suka melewatkan sekantong properti dan memiliki metode yang secara internal menangani kompleksitas, daripada memaksakan kompleksitas eksternal pada pengguna akhir. ParameterSetName hanya berguna sebagai konsep sebagai template, tidak baik untuk pemrograman. Ini mengacaukan polimorfisme ad-hoc dengan intellisense.

@jzabroski Mengenai pemformatan ErrorRecord, ada masalah terpisah yang digunakan untuk membahasnya: https://github.com/PowerShell/PowerShell/issues/3647 , karena pemformatan tidak dianggap sebagai perubahan yang mengganggu, kami dapat melakukan perbaikan di sana.

Beberapa dari permintaan Anda yang lain berpotensi aditif dan tidak merusak, jadi itu harus menjadi masalah yang berbeda. Masalah khusus ini membahas permintaan untuk melanggar perubahan jika kami memiliki kesempatan dan dapat membenarkan melakukan versi utama baru PS.

@jzabroski Mengenai pemformatan ErrorRecord, ada masalah terpisah yang digunakan untuk membahasnya: # 3647, karena pemformatan tidak dianggap sebagai perubahan yang mengganggu, kami dapat melakukan perbaikan di sana.

_Mengapa_ bukan perubahan yang merusak? Karena pengembang seharusnya tidak mencocokkan pola pada string dalam pesan kesalahan sejak awal? Saya rasa itu valid. Tapi masih akan merusak konsumen hilir.

Beberapa dari permintaan Anda yang lain berpotensi aditif dan tidak merusak, jadi itu harus menjadi masalah yang berbeda.

Mana yang menurut Anda berpotensi menimbulkan aditif? Saya dapat membuat masalah untuk mereka sehingga kami tidak menggagalkan diskusi ini, tetapi saya dengan hati-hati menyusun daftar ini pagi ini. Saya benci PowerShell dengan amarah dan hasrat menggelindingkan guntur dan kilat yang meledak. PowerShell adalah bola bowling dengan pisau daging. 5 momen paling memalukan saya sebagai seorang insinyur semuanya terjadi saat menggunakan PowerShell. Saya tidak akan pernah mendapatkan waktu itu kembali.

Saya telah memperbarui saran saya untuk memperjelas mengapa ini melanggar saran perubahan (dan mengagumkan).

Output terakumulasi; return tidak melakukan hal yang sama seperti bahasa lain; memperbaikinya.

return berperilaku seperti yang Anda harapkan dalam metode class . Cara "output terakumulasi" dalam fungsi PS biasa / lanjutan cukup umum untuk lingkungan skrip shell misalnya Korn shell dan Bash. Artinya, salin beberapa perintah dari konsol dan letakkan dalam sebuah fungsi. Saat Anda menjalankan fungsi itu, ia akan mengeluarkan dari setiap perintah seperti saat Anda menjalankan perintah tersebut dari konsol.

Keluhan utama saya dengan PowerShell adalah bahwa dalam kasus fungsi biasa / lanjutan, return seharusnya tidak pernah mengambil argumen. Karena sesuatu seperti:

return $foo

benar-benar dijalankan sebagai:

$foo
return

Ini memberi orang perasaan bahwa mereka dapat mengontrol output dengan menggunakan return dan mereka tidak bisa.

return berperilaku seperti yang Anda harapkan dalam metode class . Cara "output terakumulasi" dalam fungsi PS biasa / lanjutan cukup umum untuk lingkungan skrip shell misalnya Korn shell dan Bash.

Saya mendengar orang mengatakan ini, termasuk @BrucePay (lihat penekanan saya , di bawah, mengutip dia), tetapi intinya adalah:

Hanya di PowerShell kita memiliki "pengembalian tidak kembali" yang tidak logis ini dan keluaran terakumulasi. Ini adalah kebocoran memori yang dimuliakan, dan Anda harus memikirkannya seperti itu.

Sejujurnya, di mana pun di PowerShell In Action saya mencari frasa "masalah", saya dapat menambahkan sesuatu ke daftar vZeroTechnicalDebt. Inilah yang Bruce tulis tentang pernyataan return:

7.3 MENGEMBALIKAN NILAI DARI FUNGSI
Sekarang saatnya berbicara tentang mengembalikan nilai dari fungsi. Kami telah melakukan ini selama ini, tetapi ada sesuatu yang perlu kami soroti. Karena PowerShell adalah shell, ia tidak mengembalikan hasil — ia menulis keluaran atau memancarkan objek. Seperti yang Anda lihat, hasil dari ekspresi atau pipeline apa pun adalah memancarkan objek result ke pemanggil. Pada baris perintah, jika Anda mengetikkan tiga ekspresi yang dipisahkan oleh titik koma, hasil dari ketiga pernyataan tersebut adalah keluaran:
[...]
Dalam pendekatan tradisional, Anda harus menginisialisasi variabel hasil, $result , untuk menahan array yang sedang diproduksi, menambahkan setiap elemen ke array, dan kemudian memancarkan array:

PS (16) > function tradnum
> {
> $result = @()
> $i=1
> while ($i -le 10)
> {
> $result += $i
> $i++
> }
> $result
> }

Kode ini jauh lebih kompleks: Anda harus mengelola dua variabel dalam fungsi sekarang, bukan satu. Jika Anda menulis dalam bahasa yang tidak secara otomatis memperluas ukuran array, itu akan menjadi lebih rumit, karena Anda harus menambahkan kode untuk mengubah ukuran array secara manual. Dan meskipun PowerShell akan secara otomatis mengubah ukuran larik, itu tidak efisien dibandingkan dengan menangkap keluaran yang dialirkan. Intinya adalah membuat Anda berpikir tentang bagaimana Anda dapat menggunakan fasilitas yang ditawarkan PowerShell untuk ditingkatkan
kode Anda. Jika Anda menemukan diri Anda menulis kode yang secara eksplisit membangun array, pertimbangkan untuk melihatnya untuk melihat apakah itu dapat ditulis ulang untuk memanfaatkan streaming.

Saya pikir motivasi di balik fitur ini bagus, tetapi ada cara yang jauh lebih bersih dan lebih mudah dibaca untuk mencapai tujuan yang sama: Promosi implisit dari satu objek ke kumpulan objek. Selain itu, PowerShell sudah memiliki cara sederhana untuk mengembalikan keluaran untuk pengalihan: Write-Output .

Di Bash, return keluar dari fungsi, titik.

Hah? Bash mengakumulasi output sama:

hillr@Keith-Dell8500:~$ function foo() {
> echo "Hello"
> ls ~
> date
> return
> echo "World"
> }
hillr@Keith-Dell8500:~$ foo
Hello
bar.ps1  date.txt   test.ps1
baz.ps1  dotnet    powershell-preview_6.2.0-rc.1-1.ubuntu.16.04_amd64.deb
Tue Mar 26 16:06:18 DST 2019

Sama seperti PowerShell, Bash masih mengeluarkan semuanya dari setiap perintah hingga pernyataan return .

Ah, saya pikir Anda mengacu pada apa yang dikembalikan dalam $? . Ya, itu perbedaan. Saya pikir itu harus int mengembalikan nilai di Bash untuk menunjukkan keberhasilan / kegagalan. Di PS, $? menunjukkan keberhasilan / kegagalan sebagai bool berdasarkan kesalahan yang dihasilkan oleh fungsi. Dalam praktiknya, saya tidak berpikir $? tidak banyak digunakan. Saya menggunakan penanganan pengecualian melalui try/catch/finally sebagai gantinya.

Iya. return hanya memiliki satu tujuan dalam bahasa tersebut. Di PowerShell, ini dicampur dengan output. Mencampur nilai balik dan aliran keluaran adalah ide yang buruk. Ini juga dapat menyebabkan gangguan kinerja seperti kebocoran memori. Yang benar-benar Anda inginkan adalah rutinitas bersama atau "pengembalian hasil", atau generator, pembuat generator, dan pemindai (seperti pada Ikon). Alasannya adalah bahwa konsumsi input malas dan kegagalan menghentikan komputasi sementara membiarkan porsi komputasi yang dihasilkan sejauh ini untuk dibuang.

Anda dapat menganggap "pengalihan keluaran" sebenarnya sebagai dua objek: Prosesor dan Konteks Prosesor.

Sunting: Saya mengerti mengapa Anda membantah poin asli saya. Anda pikir saya mengatakan buruk untuk dapat menghasilkan output. Saya malah mengatakan buruk untuk mengembalikan output dengan cara PowerShell melakukannya.

Saya menggunakan penanganan pengecualian melalui try/catch/finally sebagai gantinya.

Itu banyak mengetik, dan tidak secara jelas mengungkapkan maksud dalam semua kasus.

Nah, PowerShell didasarkan pada .NET yang mengumpulkan sampah, jadi seharusnya tidak mengalami "kebocoran" memori. Itu tidak berarti Anda tidak dapat memiliki penimbunan memori. Jadi Anda harus sedikit berhati-hati saat menangani output / koleksi besar yang ditugaskan ke variabel atau memasukkan semacam hashtable.

Saya pikir pernyataan PowerShell return seharusnya hanya memiliki satu tujuan dan itu untuk kembali lebih awal - tidak ada yang lain. Ketika seseorang melakukan return 42 itu tidak ada hubungannya dengan $? . Ini hanyalah keluaran item (dihasilkan) ke arus keluaran.

Seperti yang saya sebutkan sebelumnya, $? dikelola oleh PowerShell dan tidak ada hubungannya dengan fungsi yang dihasilkan / dikembalikan. $? disetel berdasarkan kesalahan yang dihasilkan (atau kekurangannya). Ini berarti bahwa ketika Anda mengeksekusi $res = foo - $ res akan berisi setiap output objek oleh fungsi foo. Jika Anda ingin mengetahui apakah fungsi "gagal" Anda dapat memeriksa $? pada setiap perintah yang Anda jalankan ATAU Anda dapat menggabungkan banyak perintah dalam blok try/catch . Saya menemukan yang pertama lebih sedikit mengetik (dalam skrip).

dengar orang mengatakan ini, termasuk @BrucePay (lihat penekanan saya, di bawah, mengutip dia), tetapi intinya adalah:
Di Korn Shell, return keluar dari fungsi, titik.
Di Bash, return keluar dari fungsi, titik.

Di PowerShell, return keluar dari fungsi juga:

PS C:\> function test { "hello"; return "!"; "world"}
PS C:\> test
hello
!

Mencampur nilai balik dan aliran keluaran adalah ide yang buruk. Ini juga dapat menyebabkan gangguan kinerja seperti kebocoran memori

Tidak ada pencampuran karena tidak ada perbedaan antara aliran keluaran dan nilai kembali di PowerShell. Anda berbicara seolah-olah fungsi tersebut menulis string ke stdout dan secara terpisah mengembalikan tanda seru ke pemanggil, tetapi ternyata tidak. Menunjuk ke write-output sepertinya merupakan kesalahan yang sama; semua ini: write-output 'x' , 'x' , return 'x' kirim sesuatu ke jalur keluaran yang sama, ke pipeline. Tidak ada nilai pengembalian yang terpisah.

Yang benar-benar Anda inginkan adalah rutinitas bersama atau "pengembalian hasil", atau generator, pembuat generator, dan pemindai (seperti pada Ikon). T

Itu berarti bahwa jika Anda menulis perintah pada baris perintah, lalu memasukkannya ke dalam skrip atau fungsi, perilakunya akan berbeda:

PS C:\> robocopy /whatever
PS C:\> "robocopy /whatever" | set-content test.ps1; .\test.ps1
PS C:\> function test { robocopy /whatever }

Saya suka melihat output yang sama dalam ketiga kasus, tidak ada output yang tertelan dalam dua kasus karena saya tidak yield return tanpa alasan. Cara PowerShell melakukannya secara konsisten dan nyaman untuk shell dan menulis skrip shell / batch - mengambil sesuatu yang Anda tulis di baris perintah dan meletakkannya di suatu tempat yang dapat Anda panggil berulang kali. Melakukan hal itu seharusnya tidak sepenuhnya mengubah perilaku kode.

Alasannya adalah bahwa konsumsi input malas dan kegagalan menghentikan komputasi sementara membiarkan porsi komputasi yang dihasilkan sejauh ini untuk dibuang.

Pipeline PowerShell dikontrol oleh runtime, jika saya mengerti apa yang Anda katakan, itu sudah dapat dilakukan:

PS D:\> 1..1mb |foreach { write-verbose -Verbose "incoming number: $_"; $_ } |select -first 3
VERBOSE: incoming number: 1
1
VERBOSE: incoming number: 2
2
VERBOSE: incoming number: 3
3

select akan menghentikan pipa segera setelah memiliki tiga hal Sisa dari satu juta nomor tidak dimasukkan ke dalam foreach . Informasi bergerak ke bawah pipa adalah model "dorong", tetapi dikontrol oleh mesin PowerShell.

Meskipun, sebagai shell, tidak jelas apa artinya untuk "kegagalan input untuk menangguhkan komputasi" jika masukan berasal dari perintah asli atau sesuatu di luar cmdlet PS.

Menyediakan "modul yang dikompilasi" mirip dengan bagaimana file Py dikompilasi ke file pyc untuk peningkatan kinerja.

Saya pikir solusi yang dimaksudkan untuk kinerja lebih adalah menulis modul dalam C #. Kode PowerShell memang mendapatkan JIT yang dikompilasi, dalam beberapa situasi, tetapi anggota tim PS telah mengatakan sebelumnya bahwa mereka tidak memiliki rencana untuk mengekspos ini kepada pengguna akhir untuk penyesuaian, misalnya pembicaraan PS Conf Asia dari IIRC

Perbaiki pengalihan null sehingga tiga cara berbeda untuk mengalihkan aliran output ke perangkat null memiliki performa yang setara.

Diinginkan, tetapi tampaknya tidak mungkin; $null = 4 adalah variable bind sederhana, 4 | out-null membutuhkan overhead untuk memulai pipeline dan melakukan resolusi perintah - bagaimana jika seseorang dengan sengaja membuat out-null proxy-wrapper yang menambahkan logging kode? Apakah itu utang teknis, bahwa meminta pipa dan cmdlet untuk dijalankan lebih lambat daripada ekspresi?

Perbaiki pelingkupan dinamis:

Jika maksud Anda "jangan gunakan pelingkupan dinamis", itu adalah pilihan yang disengaja, misalnya Bruce Payette di sini mengatakan "pelingkupan dinamis, ini hampir tidak pernah digunakan; sebelumnya, seperti 30 tahun yang lalu LISP memiliki pelingkupan dinamis, tetapi sangat jarang digunakan sekarang. Alasan kami menggunakannya adalah: itulah yang digunakan shell. Shell menggunakan ekuivalen dengan cakupan dinamis, bahkan Bash, dan shell Unix menggunakan ekuivalen cakupan dinamis, di mana variabel dari konteks pemanggil - dalam kasusnya variabel dari konteks pemanggil disalin ke dalam konteks anak. [..] Dengan satu modifikasi, biasanya dalam pelingkupan dinamis Anda mencari rantai panggilan dan mengatur variabel di mana itu ada, kami tidak melakukannya, kami menetapkan variabel dalam lingkup saat ini sepanjang waktu, dan sekali lagi itu meniru perilaku cangkang ".

Itu mungkin mengganggu, tetapi apakah itu "hutang teknis" untuk sebuah shell, dan akan menjadi "zeroTechnicalDebt" jika diubah?

Nah, PowerShell didasarkan pada .NET yang mengumpulkan sampah, jadi seharusnya tidak mengalami "kebocoran" memori. Itu tidak berarti Anda tidak dapat memiliki penimbunan memori. Jadi Anda harus sedikit berhati-hati saat menangani output / koleksi besar yang ditugaskan ke variabel atau memasukkan semacam hashtable.

Saya memiliki administrator sistem, yang bukan insinyur, menulis beberapa logika untuk mencoba membuat tabulasi metadata pada semua file pada file share 8 TB. Itu tidak berakhir dengan baik: Ini memakan banyak memori, dan juga mematok sistem pada 100% cpu ... kami bahkan tidak dapat masuk ke kotak setelah skrip dimulai, dan satu-satunya solusi _ dalam produksi_ untuk menyelamatkan server sulit untuk mem-boot ulangnya.

Menurut pengalaman saya, PowerShell memudahkan penulisan sampah semacam itu. Anda dapat melakukan, dan mengkritik, tanggapan saya sesuka Anda. Ini tidak akan mengubah fakta bahwa PowerShell memudahkan penulisan skrip yang dapat merusak mesin produksi secara efektif.

@jzabroski dapatkah Anda membagikan detail skrip?

Orang-orang Powershell mencoba mendorong streaming pipa ( get-childitem | foreach-object {} ) alih-alih memuat sebelumnya set data ( $files = get-childitem; $files | foreach-object ) dengan sengaja untuk mengurangi penggunaan memori. Apakah itu melakukan pemuatan di muka?

Apakah ada penggunaan Group-Object untuk mengumpulkan file serupa? Ada peningkatan dalam kinerja Group-Object baru-baru ini yang akan mengurangi penggunaan CPU, jika tidak menggunakan memori.

PowerShell adalah single-core secara default, apakah ada kode pekerjaan / runspaces di sana, apakah itu server inti tunggal? PS 6.1 memiliki Start-ThreadJob yang memungkinkan banyak pekerjaan dengan overhead dan throttling yang jauh lebih sedikit untuk membantu mengontrol penggunaan CPU.

Menurut pengalaman saya, PowerShell memudahkan penulisan sampah semacam itu

Semua tutorial dan buku yang memberitahu Anda untuk menulis $files = @(); $files += $f pasti menghabiskan banyak uang dalam siklus cpu dan memori. Itu adalah pola yang lambat, mahal untuk prosesor dan memori, dan sangat umum. Saya ingin tahu apakah pola itu ada dalam skrip? (Dan jika ada cara kita bisa memblokirnya tanpa merusak kompatibilitas mundur, atau membuat + = tidak valid pada array di masa depan yang melanggar-perubahan?).

Tapi, ada pengorbanan di sini. Get-ChildItem -Recurse adalah 22 karakter dan memakan 800 + MB RAM hanya pada drive C: saya, C # untuk melakukannya tanpa menggunakan banyak memori adalah 50+ baris dan tidak mendapatkan file metadata sama sekali, dan akan lebih seperti 80MB. Itu bukan PS yang membocorkan memori, itu PS menggunakannya untuk mendapatkan kenyamanan pengguna.

Adakah bahasa di mana Anda tidak perlu peduli dengan detail cara kerjanya, dapat menulis kode yang berguna, tidak dapat menulis kode yang buruk, dan tidak harus menjadi pemrogram yang terampil? (Dan yang juga merupakan cangkang?)

Apakah salah satu perubahan yang Anda usulkan sebelumnya telah berhasil sehingga skrip berfungsi?

Anda dapat menulis skrip Bash untuk membuat daftar file, menelurkan proses untuk masing-masing file, hingga server Anda jatuh dan Anda bahkan tidak dapat melakukan SSH ke dalamnya. Anda dapat menulis skrip Python yang os.walk() s pohon file dan memanggil os.stat() untuk setiap file dan menggunakan lebih sedikit memori dan menyelesaikan lebih cepat - tetapi membutuhkan 10 baris alih-alih 1 dan Anda masih harus peduli OS dan peduli tentang detail kode (dan ini masih bukan shell, dan tidak akan berfungsi dengan Penyedia PS).

Saya ingin PS memiliki lebih banyak "lubang kesuksesan" dan lebih sedikit bahaya perjalanan. Daftar nama file yang cepat menjadi salah satunya yang saya lihat banyak gunanya. Mengubahnya secara radikal menjadi bahasa yang sama sekali berbeda, dan memincangkan area yang dikerjakannya dengan baik, tidak akan berhasil.

Anda ingin Python, Python ada, bahasanya indah, tidak tertatih-tatih dengan mencoba menyesuaikan diri dalam dua dunia yang berbeda dan tetap menjalankan semantik cakupan dan fungsi dari shell berusia tiga puluh tahun dari OS yang berbeda (mengapa, Microsoft), atau dengan komitmen Microsoft untuk kompatibilitas mundur (dan obsesi dengan .Net), sehingga dapat menghindari semua pertanyaan itu, daripada menghadapinya.

Saya ingin PS memiliki lebih banyak "lubang kesuksesan" dan lebih sedikit bahaya perjalanan.

Jika saya bisa menambahkan dua puluh jempol untuk itu saja, saya akan melakukannya. Inilah pola dan pendekatan yang perlu diambil PowerShell.

For-EachObject adalah fungsi PowerShell untuk mengambil koleksi PowerShell dan mengubahnya menjadi pelacakan tumpukan yang tidak dapat dibaca.

Hari ini, saya mengambil skrip yang ditulis oleh Amazon untuk mencantumkan EC2 Windows Disks: https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2-windows-volumes.html#windows -list-disks

Tebak apa? Saya tidak memiliki Initialize-AWSDefaults set-up di PC ini, dan karena penulis skrip menggunakan ForEach-Object, jejak tumpukan saya terlihat seperti ini _garbage_:

PS C:\Windows\system32> D:\Installs\PowerShell\List-EC2Disks.ps1
Could not access the AWS API, therefore, VolumeId is not available. 
Verify that you provided your access keys.
ForEach-Object : You cannot call a method on a null-valued expression.
At D:\Installs\PowerShell\List-EC2Disks.ps1:39 char:12
+ Get-disk | ForEach-Object {
+            ~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [ForEach-Object], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull,Microsoft.PowerShell.Commands.ForEachObjectCommand

Ini terjadi _setiap kali orang menggunakan ekspresi ForEach-Object dalam kode mereka_. Jejak tumpukan _selalu mengerikan_. Menulis ulang ini menyakitkan. Untungnya, itu hanya skrip yang saya salin-tempel ke file acak, simpan, dan jalankan. Jika ini adalah masalah dalam modul besar, saya harus mendapatkan kode sumber untuk modul, menulis ulang skripnya, berharap kepada tuhan dalam refactoringnya saya tidak merusak apa pun di modul dengan mengubah ekspresi ForEach-Object DAN harapan Saya bisa mencari tahu di mana letak kesalahan REAL supaya saya bisa _melakukan pekerjaan saya_. Dan sekarang saya memiliki beberapa kode khusus yang saya buat dari beberapa repositori utama, hanya untuk mencari tahu mengapa saya mendapatkan beberapa kesalahan karena PowerShell Write-Error MENGERIKAN dibandingkan dengan idiom sederhana C # throw new Exception("message", ex) .

Menulis ulang ini untuk menggunakan for ($var in $list) , mengumpulkan hasil dalam variabel $results , saya mendapatkan kesalahan berikut:

PS C:\Windows\system32> D:\Installs\PowerShell\List-EC2Disks.ps1
Could not access the AWS API, therefore, VolumeId is not available. 
Verify that you provided your access keys.
You cannot call a method on a null-valued expression.
At D:\Installs\PowerShell\List-EC2Disks.ps1:58 char:26
+ ... lDevice = If ($VirtualDeviceMap.ContainsKey($BlockDeviceName)) { $Vir ...
+                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

Oh, dan omong-omong, setiap kali saya harus melakukan ini, saya tidak dapat mengingat aturan bodoh PowerShell untuk menambahkan item ke daftar, jadi saya harus ke Google https://www.google.com/search?q=powershell+append + ke + daftar dan baca entri blog tentang seseorang yang menjelaskan bagaimana operasi daftar PowerShell yang tidak intuitif.

Jika Anda tidak tahu C # atau bahasa yang bisa melakukannya dengan baik, mudah untuk mengatakan bahwa perilaku ini OK. Namun, C # menangani masalah ini secara cerdas dengan membungkus pengecualian dalam AggregateException, sehingga Anda mendapatkan pengecualian dalam dan luar. PowerShell? Hahahaha. Ya, itu akan sangat berguna.

@jzabroski dapatkah Anda membagikan detail skrip?

Sayangnya (_ dan bahagia _), saya tidak mengingatnya. Itu adalah fileshare, jadi hampir pasti satu atau dua core paling banyak. Jika itu dua inti, CPU yang tersisa kemungkinan besar diambil oleh Windows Defender.

Edit: Ditemukan di obrolan Teams.

$big32 = Get-ChildItem D:\Data\Website\Data -recurse | Sort-Object length -descending | select-object -first 32 | measure-object -property length –sum

Sebagai bonus tambahan, saya baru saja berbicara dengan orang yang menjalankan perintah ini (dan merasa sangat buruk), dan dia mengatakan kasus penggunaan "adalah mengambil 32 file terbesar untuk persyaratan ukuran grup replikasi awal untuk DFS".

Tidak ada pencampuran karena tidak ada perbedaan antara aliran keluaran dan nilai kembali di PowerShell.

Saya belum melihat orang menggunakan ini dengan benar pada percobaan pertama. Sekali lagi, ini bukan yang dilakukan bash atau shell lainnya. Meskipun itu adalah eksperimen yang menarik untuk menyatukan dua konsep, itu adalah bencana yang lengkap dan total dari sudut pandang keterbacaan. Tidak membantu jika Write-Output rusak di PowerShell v6 selama 16 bulan.

@jzabroski dari output Anda For-EachObject sepertinya Anda tidak menggunakan Powershell Core (untuk itulah repositori ini didedikasikan) dapatkah Anda mencoba inti Powershell dan melihat apakah Anda dapat mereproduksinya. Pastikan untuk menggunakan versi terbaru. Berhati-hatilah, bahwa fungsionalitas khusus windows (seperti Get-Disk) bukan bagian dari Powershell Core, Anda perlu mempertimbangkan ini, saat melakukan pengujian.

Saya belum melihat orang menggunakan ini dengan benar pada percobaan pertama. Sekali lagi, ini bukan yang dilakukan bash atau shell lainnya.

$ test () { ls /tmp; ls /etc/pm; return 5; ls /v*; } ; x=$(test)
$ echo "$x"
tmux-1000
sleep.d
$ echo $?
0

Itu adalah output dari dua perintah terpisah yang terakumulasi dalam fungsi Bash, dan Bash kembali tidak berfungsi sebagai fungsi pengembalian di C #. Apa, secara khusus, "bukankah yang dilakukan Bash"?

Anda tidak menangkap nilai pengembalian dengan benar untuk contoh bash. pengembaliannya hilang karena $? selalu menjadi perintah terakhir. dalam kasus Anda 'echo'.

$ test () { ls /tmp; ls /etc/pm; return 5; ls /v*; } ; x=$(test)
$ echo $?
5
$ echo $x
tmux-1000
sleep.d

POWERSHELL melakukan ini secara berbeda

> function test() { ls; return 5 ; ls } ; $x=test
> echo $?
True
> echo $x
    Directory: c:\foo\bar

Mode                LastWriteTime         Length Name
----                -------------         ------ ----

Keanehan PowerShell lainnya:

Chocolatey menambahkan RefreshEnv.cmd yang merupakan GODSEND. Mengapa ini tidak dikirimkan dengan PowerShell saja? Mengapa saya perlu memulai ulang Shell saya atau mengunduh beberapa skrip bodoh dari Internet untuk mengatur ulang $ env saya?

@jzabroski Ini dibicarakan di https://github.com/PowerShell/PowerShell-RFC/pull/92 Anda mungkin ingin berpadu di sana.

Buat model objek standar untuk penyedia PowerShell: https://github.com/PowerShell/SHiPS/issues/66#issuecomment -368924485

Di tautan pada SHiPS edisi 66, saya menguraikan kemungkinan cmdlet kandidat. Tidak jelas bagi saya mengapa kami tidak dapat mengimplementasikan sesuatu seperti perilaku kelas tipe Haskell untuk cmdlet inti ini.

API ini sudah ada di PowerShell.

@iSazonov Bisakah Anda mengedit dan mengutip apa yang Anda balas, dan menambahkan beberapa konteks, seperti hyperlink ke dokumentasi API tersebut? TYVM

@jzabroski Lihat file di folder srcSystem.Management.Automationnamespaces.

POWERSHELL melakukan ini secara berbeda

Itu bash yang melakukannya secara berbeda - return hanya dapat mengatur kode keluar proses (integer) (bukan itu yang dimaksud dengan "kembali" dalam bahasa pemrograman lain, itu exit ) .

PowerShell juga dapat melakukannya , dengan exit 5

Hanya saja kami tidak terlalu sering menggunakan kode keluar di PowerShell (cukup banyak hanya untuk tugas terjadwal dan interop dengan OS lain), karena ini bukan shell berbasis proses, dan fungsi tidak boleh keluar.

Pada akhirnya, itu alasan yang sama mengapa mendeteksi tipe pegangan stdout tidak berguna di PowerShell (dan mengapa "mengalihkan" ke out-null tidak sama dengan mentransmisikan ke [void] atau menetapkan ke $null )

Saya merekomendasikan orang-orang mengajukan masalah baru jika mereka benar-benar memiliki umpan balik yang ingin mereka tindak lanjuti - karena tim telah _ secara jelas dan tegas mengesampingkan_ versi PowerShell yang tidak kompatibel mundur, saya tidak tahu mengapa utas ini terus berjalan ...

karena tim telah _ dengan jelas dan tegas mengesampingkan_ versi yang tidak kompatibel dengan versi sebelumnya

Itu berita baru bagi saya. Bagaimana ini jelas? Harap berikan tautan ke postingan atau dokumentasi lainnya.

Agak frustasi bagi sebagian dari kita untuk mendengar "kita tidak akan pernah merusak kompatibilitas" sementara kita bergumul dengan beberapa kerusakan setiap hari. Inti dari utas ini adalah agar pasar bebas ide dapat menyelesaikan beberapa masalah ini ketika hulu tidak.

Seseorang mungkin merasa cukup menguntungkan untuk membayar PowerShell dan membuat versi dengan hutang teknis minimal. Kelompok itu akan mendapat manfaat dari ide-ide yang disajikan di utas ini. (Beginilah cara dunia bekerja sekarang. Semoga PowerShell terbaik menang.)

Saya akan tegaskan kembali bahwa tim telah menghasilkan versi 'not-backward compat' dari PowerShell dengan mengganti nama perintah dari PowerShell menjadi pwsh. Power (SHELL) adalah cangkang. tugas cangkang adalah menjadi perekat bagi manusia yang mengikat sistem digital. Ini bukan biner terkompilasi dengan dependensi eksternal minimal. Bahkan bahasa pemrograman tradisional merencanakan dan membuat perubahan besar.

POWERSHELL melakukan ini secara berbeda

bash yang melakukannya secara berbeda - return hanya dapat menyetel kode keluar proses (integer) (bukan

Saya ingin tahu tentang cangkang lainnya. Apa yang mereka lakukan? korn, csh, dll.

Berikut adalah artikel yang membahas pernyataan pengembalian dalam berbagai bahasa: https://en.wikipedia.org/wiki/Return_statement

Ini menyebutkan bahwa sistem operasi [shell] memungkinkan beberapa hal untuk dikembalikan: kode pengembalian dan keluaran.

Tim saya memiliki berbagai skrip yang hanya berjalan di PowerShell 5 meskipun kami menggunakan PowerShell 6 sebanyak mungkin. Dalam pengalaman saya, premis bahwa PowerShell benar-benar kompatibel ke belakang jelas salah. Setidaknya ada beberapa kasus ekstrim (misal: ErrorActionPreference tidak berperilaku secara intuitif) yang harus ditangani sebagai perubahan yang merusak - kasus di mana membuat perbaikan akan kurang "merusak" daripada tidak melakukannya.

@chriskuech apakah ada masalah yang merinci masalah Anda dengan ErrorActionPreference ?

@ SteveL-MSFT Saya yakin Mosaik yang ditautkan oleh @KirkMunro langsung di bawah komentar @chriskuech adalah masalah yang Anda cari. Dan ya, saya memasukkan kata Mosaic ke dalam percakapan teknologi.

Meskipun demikian , @chriskuech edisi asli pada 1 Oktober 2018: Lihat https://github.com/PowerShell/PowerShell/issues/7774

Tampaknya hal ini terus bermunculan, dalam bentuk yang berbeda, dan Komite terus menutup permasalahan di sekitarnya.

@jzabroski menemukan masalah utama saya yang menargetkan akar masalah.

Saya juga pernah mengajukan masalah di masa lalu tentang salah satu gejala: Invoke-WebRequest melakukan kesalahan penghentian. Saya pribadi telah menyaksikan banyak orang benar-benar tercengang di sekitar seluruh try / catch boilerplate untuk menangani permintaan HTTP yang gagal, yang terjadi karena metode .NET internal melempar kesalahan penghentian. Dalam masing-masing dari tiga kasus yang berbeda, insinyur tersebut menanggapi dengan umpatan ketika saya menjelaskan perilaku yang mendasarinya dan mengapa masalah tersebut diduga tidak akan pernah bisa diperbaiki.

Untuk meringkas , menghentikan kesalahan menghentikan skrip karena pembuat PowerShell percaya skrip tidak dapat secara logis melanjutkan melampaui kesalahan, tetapi saya tidak berpikir itu benar-benar siapa pun kecuali keputusan pembuat skrip untuk membuat kasus per kasus. Hanya pembuat skrip yang dapat memutuskan apakah mereka ingin skrip menjadi Stop , SilentlyContinue , Continue , dll.

(Bersinggungan dengan masalah di atas)

Jika PowerShell mengimplementasikan mode opt-in "ZeroTechDebt", saya pasti berpikir bahwa $ErrorActionPreference = "Stop" harus disetel secara default. Jelas, pengaturan ini tidak masuk akal dalam REPL dan oleh karena itu tidak boleh disetel secara default untuk semua skenario, tetapi secara harfiah semua skrip saya diawali dengan $ErrorActionPreference = "Stop" untuk mengaktifkan "pemrograman defensif" dan berperilaku seperti "normal " bahasa pemrograman.

@chriskuech Jika Anda belum melakukannya, silakan lihat koleksi RFC ini: https://github.com/PowerShell/PowerShell-RFC/pull/187. Mereka berbicara langsung dengan apa yang Anda bicarakan di sini tanpa memerlukan PowerShell versi utang teknologi nol baru.

Anda juga dapat menemukan empat RFC dalam terbitan terpisah pada halaman Masalah di repo tersebut jika itu membuatnya lebih mudah untuk dibaca / dicerna. Cari saja masalah terbuka yang saya posting dan Anda akan menemukannya

@ SteveL-MSFT Berikut adalah masalah serupa yang menghambat produktivitas saya. Ini bukan $ErrorActionPreference tapi $ConfirmPreference :

Di bawah ini adalah skrip jelek yang saya tulis untuk mengatur volume disk SQL Server ke 64kb.

Import-Module Storage;

function Format-Drives
{
    # See https://stackoverflow.com/a/42621174/1040437 (Formatting a disk using PowerShell without prompting for confirmation)
    $currentconfirm = $ConfirmPreference
    $ConfirmPreference = 'none'

    Get-Disk | Where isOffline | Set-Disk -isOffline $false
    # The next line of this script is (almost) copy-pasted verbatim from: https://blogs.technet.microsoft.com/heyscriptingguy/2013/05/29/use-powershell-to-initialize-raw-disks-and-to-partition-and-format-volumes/
    Get-Disk | Where partitionstyle -eq 'raw' | Initialize-Disk -PartitionStyle MBR -Confirm:$false -PassThru | New-Partition -AssignDriveLetter -UseMaximumSize -IsActive | Format-Volume -FileSystem NTFS -AllocationUnitSize 64kb -Confirm:$false

    # See https://stackoverflow.com/a/42621174/1040437 (Formatting a disk using PowerShell without prompting for confirmation)
    $ConfirmPreference = $currentconfirm
}

Format-Drives

Beberapa poin samping:

  1. Dokumentasi untuk Format-Volume menginginkan lebih. Hanya dua contoh? Dan dokumentasi resmi tidak sinkron dengan situs web: https://github.com/MicrosoftDocs/windows-powershell-docs/issues/1170
  2. Mengapa saya perlu membuka StackOverflow untuk mempelajari cara menghindari GUI untuk bahasa skrip?
  3. Fakta bahwa ini sangat rawan kesalahan / sangat sulit untuk menulis "tanpa berpikir" hanya menggarisbawahi masalah terkait seperti https://github.com/PowerShell/PowerShell-RFC/issues/198 - ini adalah contoh lain bagaimana janji Bruce Payette dalam " PowerShell In Action "yang Anda ketik saja apa yang menurut Anda benar dan berhasil ... sepenuhnya dan sepenuhnya salah.
  4. Lihat juga masalah @ mklement0 : https://github.com/PowerShell/PowerShell/issues/4568

Membutuhkan -Versi tidak memiliki cara untuk menentukan versi maksimal

Lihat: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_requires?view=powershell-6

Ini mengganggu saat Anda menulis Fungsi Lanjutan yang memuat pustaka .NET Framework di mana API benar-benar berbeda antara .NET Framework dan .NET Core, seperti cara kerja AccessControl API.

@jzabroski Anda dapat menentukan edisi, bagaimanapun, untuk memisahkannya:

#requires -PSEdition Desktop
# versus
#requires -PSEdition Core

Sekadar catatan singkat bahwa @rjmholt telah secara resmi memulai diskusi tentang cara menerapkan dan mengelola perubahan yang dapat

Plus, # 6817 dan # 10967 adalah lebih banyak perilaku yang perlu ditinjau kembali setelah perubahan yang melanggar diperbolehkan.
(Mereka memiliki akar penyebab yang sama, dijelaskan di https://github.com/PowerShell/PowerShell/issues/10967#issuecomment-561843650).

Fakta bahwa , lebih kuat dari + adalah logis, karena PowerShell lebih tentang daftar daripada tentang angka. MENURUT OPINI SAYA.

@rjmholt secara resmi memulai diskusi

Saya harus mengatakan itu tidak lebih resmi daripada diskusi lainnya

Saya ingin sekali melakukan pemeriksaan ketat pada impor dan waktu pengeditan tanda tangan fungsi.
Apakah Anda mempertimbangkan untuk memperkenalkan semantik impor baru seperti yang disediakan modul EcmaScript?
Tidak ada lagi polusi namespace global. Mekanika impor lambat.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

HumanEquivalentUnit picture HumanEquivalentUnit  ·  3Komentar

andschwa picture andschwa  ·  3Komentar

garegin16 picture garegin16  ·  3Komentar

JohnLBevan picture JohnLBevan  ·  3Komentar

rkeithhill picture rkeithhill  ·  3Komentar