Saat mengetik cd..
tanpa spasi di antara cd
dan ..
prompt perintah Windows dengan senang hati akan beralih ke folder induk. Apakah ada penjelasan untuk perilaku ini? Perintah tidak mengikuti format standarcommand<space>arguments
Juga, mengapa ini tidak menghasilkan hasil yang konsisten?
windows
command-line
command-line-arguments
Jonas Köritz
sumber
sumber
dir/a
atau sintaks VMS serupa.cd c:\program files
tanpa tanda kutip dan masih berfungsicd..
berhasil? Karena Microsoft mengalami kesulitan membuatnya bekerja secara eksplisit.cd
adalah perintah yang dibangun ke dalam interpreter perintah Windows, dan Microsoft dapat membuat interpreter mereka melakukan apa pun yang mereka inginkan. (Sebagai contoh lain,cd
juga tidak perlu mengutip direktori dengan spasi dalam nama.)Jawaban:
Seperti yang dicatat oleh beberapa jawaban / komentar lain, gagasan bahwa harus ada spasi setelah perintah tidak benar. Contoh terkenal adalah bahwa Anda dapat mengetikkan garis miring setelah perintah, tanpa perlu spasi terlebih dahulu.
Namun, ada perilaku lain yang sedikit kurang dipahami, dan memungkinkan "
cd..
" yang Anda tanyakan. Perilaku ini juga memungkinkan "cd\
" bekerja.Perilaku yang Anda gambarkan konsisten untuk semua perintah internal ke juru baris perintah. Jika Anda memiliki simbol tertentu, termasuk titik, garis miring, atau garis miring terbalik, maka karakter sebelumnya diperiksa untuk melihat apakah mereka adalah perintah yang internal ke shell "command line interpreter" (CMD.EXE atau pendahulunya COMMAND.COM ).
Ini dapat dilakukan sebelum memeriksa apakah kata tersebut merujuk pada file atau subdirektori. Itu benar untuk
cd
perintah. Tragisnya, ketika membuat sampel, saya menemukan bahwa ini tidak terjadi dengancopy
perintah, sehingga hasilnya tidak konsisten: mereka tidak harus sama dengan semua perintah internal. Saya tidak melanjutkan pencarian saya untuk juga membandingkan (banyak) baris perintah lainnyadel
dandir
, jadi saya sarankan untuk sangat berhati-hati jika Anda mencoba untuk mengandalkan apa yang terjadi tanpa spasi.Sekarang, pertanyaannya juga ditanyakan tentang perintah echo : Ini adalah pengecualian yang tidak biasa, karena menurut saya
echo.
cukup terkenal oleh para pakar DOS. Ini mungkin didokumentasikan. Perilaku, setidaknya dalam CMD Win7 , adalah bahwa jika perintah dimulai dengan "echo.
", maka periode pertama diabaikan. Jadi, "echo..hi
" berubah menjadi output dari ".hi
". Alasannya adalah agar "echo.
" dapat digunakan untuk mencetak baris kosong. Sebaliknya, dengan Unix, Anda dapat melakukan ini hanya dengan menjalankan perintah "echo
" dengan sendirinya. Namun, di DOS, menjalankan perintah "echo
" dengan sendirinya akan menghasilkan pengaturan " gema " saat ini . Demikian pula, DOS memperlakukan "Echo *Off*
" dan "Echo *On*
"sebagai nilai khusus yang mengubah pengaturan gema saat ini. Jika Anda benar-benar ingin mencetak kata"Off
","Echo.Off
"lakukan triknya (setidaknya dengan versi terbaru dari interpreter baris perintah CMD Microsoft .)Jadi, setidaknya
echo
perintah memiliki penjelasan semi-wajar. Adapun perintah yang tersisa, saya dulu berpikir bahwa perintah internal memiliki prioritas. Namun, ketika saya mencoba melakukan beberapa tes, saya menemukan bahwa sebenarnya agak tidak konsisten. Saya menunjukkan ini melalui beberapa contoh yang saya dokumentasikan di sini.Berikut ini beberapa contohnya. Saya memang menggunakan prompt perintah yang ditinggikan, sehingga UAC tidak akan mengeluh tentang saya menulis ke direktori root. Ini dilakukan dengan CMD.EXE Microsoft Windows 7. Saya menduga perilaku mungkin berbeda dengan versi lain, seperti COMMAND.COM dari versi MS-DOS yang lebih lama, atau perangkat lunak yang dirilis oleh perusahaan lain (COMMAND.COM DR-DOS).
(Jawaban ini sudah cukup lama, jadi saya tidak termasuk perintah untuk membersihkan semua kekacauan yang saya buat pada sistem file saya. Ada sedikit pembersihan, tapi tidak banyak.)
Berikut adalah contoh yang membuktikan bahwa perintah internal menciptakan prioritas. (Saya juga menunjukkan kemampuan yang agak kurang dikenal untuk menggunakan titik dua untuk secara efektif menjadi komentar, yang juga berfungsi dengan baik dalam file batch. Secara teknis, dalam file batch, itu diproses sebagai label yang tidak dapat dijangkau oleh GOTO, dan berakhir lebih cepat dari perintah REM.)
Berikut ini adalah contoh yang memperlihatkan salinan , dengan path lengkap, tidak menggunakan prioritas yang sama (mendukung perintah internal) seperti cd ketika tidak ada ekstensi yang digunakan:
Temuan awal saya menunjukkan bahwa hasil ini menunjukkan bahwa shell baris perintah memberikan prioritas:
Ini jelas menunjukkan bahwa perilaku tidak konsisten antara perintah salin (dengan nama file lengkap termasuk ekstensi) dan perintah cd (tanpa ekstensi sebagai bagian dari nama direktori). Saat menggunakan backslash, perintah copy (dengan ekstensi nama file lengkap) akan memeriksa sistem file terlebih dahulu, tetapi perintah cd tidak akan (jika direktori tidak mengandung ekstensi).
(Pembaruan: Awalnya, saya pikir inkonsistensi didasarkan pada perilaku yang berbeda antara program. Kemudian, saya menemukan bahwa inkonsistensi memang ada, tetapi lebih disebabkan oleh parameter yang disediakan.)
Sebenarnya, bahkan poin-poin itu tidak sepenuhnya akurat, meskipun saya tampaknya hanya menunjukkan setiap hal yang saya katakan. Masalahnya adalah, bahwa daftar poin-poin tidak cukup tepat untuk sepenuhnya akurat. (Saya meninggalkan hal-hal yang tidak tepat sehingga poin-poin tersebut dapat dibandingkan dengan relatif mudah, dan diperiksa dengan relatif mudah.)
Namun, agar lebih akurat, poin pertama harus menunjukkan bahwa shell baris perintah memberikan prioritas:
Berikut ini akan menunjukkan mengapa saya membuat perbedaan itu:
(Perhatikan bahwa perintah salin terakhir mencari file yang disebut \ needext , karena perintah salin internal digunakan. File \ needext.bat hanya dibuat untuk membantu dengan mudah menunjukkan bahwa itu tidak pernah digunakan oleh baris perintah yang termasuk kata salin .)
Pada titik ini, saya menetapkan beberapa inkonsistensi (dengan perilaku perintah salin ) ketika backslash digunakan ...
Selanjutnya saya akan menunjukkan bahwa ada beberapa konsistensi antara perintah-perintah ini. (Jadi, ada konsistensi ... um ... kadang-kadang. Kita mungkin hanya memiliki konsistensi, tidak konsisten.) Apa yang akan saya tunjukkan selanjutnya adalah bahwa perintah cd berperilaku seperti perintah salin ketika suatu periode digunakan. The copy perintah menggunakan perintah internal, dan begitu juga dengan cd perintah.
Jadi, selama sesi tes awal yang sebagian besar berfokus pada perintah cd dan salin (dengan beberapa penggunaan tambahan md dan sedikit del ), satu-satunya saat kita benar-benar mengutamakan filesystem adalah dengan perintah salin , dan kemudian filesystem hanya mengambil prioritas saat menggunakan path lengkap.
Setelah ulasan selanjutnya, saya menemukan bahwa perintah cd juga memberikan prioritas filesystem ketika menggunakan ekstensi. Setidaknya ini berarti perintah-perintah internal diperlakukan sedikit lebih konsisten satu sama lain. Namun, itu juga berarti bahwa kita mendapatkan perilaku yang berbeda berdasarkan nama objek sistem file (file atau direktori). Sepertinya perilaku tersebut menggunakan logika internal yang benar-benar tidak jelas. Oleh karena itu, mengandalkan perilaku ini untuk bekerja di berbagai sistem operasi adalah sesuatu yang mungkin saya anggap tidak aman untuk dilakukan.
sumber
ipconfig
misalnya berfungsi juga.IPCONFIG/ALL
. Namun, bukan itu yang saya bicarakan. " Perilaku yang Anda gambarkan " (dalam pertanyaan Anda) adalah perilaku menempatkan periode tepat setelah nama perintah. Jika saya mengetikIPConfig.
maka saya mendapatkan kesalahan tentang perintah yang tidak ditemukan. Demikian pula (walaupun ini tidak terkait dengan perilaku yang Anda gambarkan), jika saya mengetikIPCONFIG\ALL
maka saya dapat menjalankan.\IPCONFIG\ALL.BAT
file kustom yang saya buat. Jadi/
tidak diperlakukan seperti.
atau `\`copy.exe
ataucopy.com
dalam cmd. Itu tidak bekerja - ini tidak dapat dieksekusi.ipconfig
, saya tidak setuju dengan kesimpulan Anda. Pertanyaan ini adalah tentang apa yang diketik di awal baris perintah. Windows / DOS mengidentifikasi executable dengan ekstensi nama file, sehingga Anda tidak dapat menjalankan program yang disebut "ipconfig" tanpa ekstensi (di Windows, tidak seperti Unix yang mengizinkan ini). Mengenai komentar selanjutnya, aku tidak tahu siapa "Calchas" itu. (Ketika Anda menentukan tanda pada, berikut ini biasanya karakter pertama dari pengguna yang muncul di tempat lain di halaman.) Saya setuju, menjalankan "copy.exe
" akan menggunakancopy
perintah internal (dan lulus.exe
). (Anda dapat berlari.\copy.exe
)Anda berasumsi bahwa nama perintah dan argumennya harus dipisahkan oleh spasi, khusus, tetapi ini tidak benar. Selama doa dapat ditafsirkan secara jelas, doa itu sahih.
Dalam hal ini, argumen pertama dimulai dengan
.
dan.
tidak dapat menjadi bagian dari nama perintah, jadicd
dan..
hanya diuraikan sebagai dua token yang terpisah.Biasanya, argumen pertama Anda akan mulai dengan karakter alfabet (misalnya awal jalan), sehingga akan "berdarah" ke nama perintah Anda dan menyebabkan kesalahan ... tapi itu bukan masalah sintaksis. Itu semantik.
Anda dapat melihat efek yang sama di tempat kerja dengan perintah lain, termasuk
echo
:Dalam hal ini, kita hanya mendapatkan dua periode karena ini
echo
perintah itu sendiri memiliki aturan khusus , sehingga berikut:atau, dengan ekstensi, ini:
hanya menghasilkan garis kosong. Itu kenyamanan. Rupanya itu dilaksanakan dengan mengabaikan periode terkemuka dalam argumen.
Hei, ini DOS / Batch. Anda menginginkan kewarasan? : D
sumber
cd..
cd..
:)alias cd..='cd ..'
.
dan..
yang muncul sebagai direktori di setiap direktori lain dan sejauh yang saya tahu tidak pernah dimaksudkan untuk menangkap lebih dari itu. Saya benar-benar menganggap model tersembunyi-atribut sebagai atribut file desain yang lebih bersih daripada secara implisit mengikuti dari nama file..
dalam nama file , yang berarti itu tidak bisa menjadi bagian dari nama perintah karena itu harus menjadi bagian dari argumen . Bahkan jika DOS telah membagi perintah menjadi argumen seperti yang dilakukan Unix, ia masih akan menempatkan.
perintah setelah ke dalam argumen pertama, karena tidak masuk akal untuk memasukkan karakter yang tidak valid ke dalam nama perintah.The
cd..
perintah yang benar dan itu didefinisikan seperti itu dalam perintah interpreter aslicommand.com
yang kemudian diberi namacmd.exe
.Penerjemah perintah tahu bagaimana memproses
cd..
, karena.
merupakan karakter khusus, sama seperti\
.sumber
echo.
berfungsi dengan baik, yang akan mencetak baris kosong..
tidak dijatuhkan tetapi hanya spasi ditambahkan.md.test
danmd .test
keduanya membuat direktori.test
. Mengetikcd.test
dancd .test
akan berubah menjadi direktori.test
.Ini adalah retas kompatibilitas mundur.
Penerjemah baris perintah dirancang agar kompatibel dengan perintah dari penerjemah perintah MSDOS yang asli, yang dirancang agar kompatibel dengan penerjemah perintah CP / M. Baik CP / M maupun MSDOS tidak mengizinkan a
.
dalam nama file (itu ditafsirkan sebagai pemisah antara dua bagian nama file, nama dasar dan ekstensi). Ini berarti (setidaknya untuk versi awal DOS), juru bahasa perintah dapat mengidentifikasi bahwa jika mencapai '.' (atau memang karakter lain yang ilegal dalam nama file) itu melewati akhir nama perintah dan menjadi argumen perintah. Ini cukup umum digunakan dalam DOS dan CP / M - misalnya,dir/w
adalah perintah yang sangat umum, setara dengandir /w
arti untuk membuat daftar file dalam format horizontal.Saat ini, '.' dapat muncul dalam nama file. Ini menyebabkan beberapa komplikasi dalam cara menguraikan perintah, tetapi shell masih mengidentifikasi
.
yang bukan bagian dari nama file yang tepat sebagai awal dari argumen. Ini diperlukan terutama karena jutaan pengguna telah terbiasa mengetikcd..
atau memiliki banyak file batch yang berisi itu atauecho.
sejumlah perintah serupa lainnya.sumber