Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: Batch ja Bash samassa tiedostossa

Metabolix [23.06.2024 17:32:08]

#

Windowsin Batch (CMD-skripti) ja Linuxin Bash-skripti on mahdollista yhdistää samaan tiedostoon – sillä varauksella, että Bash-skriptin alussa ei ole shebang-riviä vaan skripti pitää muuten syöttää bashille.

Lyhyin kikka on, että merkkipari :; tarkoittaa Bashille käytännössä tyhjää komentoa, jonka perään voi laittaa muun komennon, mutta Batch taas tulkitsee kaksoispisteellä alkavan rivin nimiöksi (label), jonka loppuosalla ei ole juurikaan merkitystä, kunhan se ei aiheuta törmäystä oikeasti käytettyjen sanojen kanssa.

:; echo "Tässä on Bash-koodia."
:; echo "Useamman rivin voi laittaa samalla tavalla peräkkäin."
:; echo "Viimeiseksi tarvitaan exit-komento."
:; exit

@echo off
echo Tässä on Batch-koodia.
echo Batchilla voi olla useampi rivi.

Monen rivin skriptiin on selvempi ratkaisu: Ensimmäisellä rivillä voidaan aloittaa Bashin heredoc, jonka sisään saadaan kaikki Batch-koodi. Batch-koodin loppuun laitetaan exit-komento, jotta myöhemmät rivit eivät häiritse. Heredocin jälkeen voi jatkua Bash-skripti ilman kikkailua.

:; : << '___' Hieno taikakoodi

@echo off
echo Tässä on Batch-koodia.
echo Batchin näkökulmasta ensimmäinen rivi on vain outo label.
echo Koodin lopussa exit /b lopettaa nykyisen skriptin.
exit /b

___

echo "Tässä on Bash-koodia."
cat << 'Heredoc'
  Alun << '___' aloittaa heredocin, jonka sisältö voi olla mitä vain.
  Heredoc päättyy riviin ___, joka on siis sama sana kuin alussa hipsuissa.
  Heredocin sisältö päätyy syötteenä sitä edeltävälle komennolle.
  Bashin näkökulmasta ensimmäinen rivi ei tee mitään, käytännössä näin:
  true; true Hieno taikakoodi <<< 'Batch-koodi syötteenä truelle.'
Heredoc

Vielä lyhyemmällä selviää, kun käyttää heredocin lopetusmerkkinä exit-riviä, joka muutenkin tarvitaan. Tässä koodien raja ei ole luonnostaan yhtä näkyvä, mutta jäkimmäisen osan alkuun voi toki muotoilla kommentin merkiksi.

:;:<<'exit /b'

@echo off
echo Tässä on Batch-koodia. Loppuun tarvitaan exit /b.
exit /b

echo "Tässä on Bash-koodia."

Toinen ratkaisu on hieman kryptisemmän näköinen. Ensimmäiselle riville tulee koodi, joka Bashin näkökulmasta määrittelee funktion nimeltä @goto mutta Batchin näkökulmasta on toimiva goto-komento. Tätä seuraaville riveille voidaan laittaa Bash-koodia, joka päättyy exit-komentoon. Myöhemmäksi tulee vielä rivi, joka on Batch-koodille tarpeellinen alun goto-lauseen kohde ja aloittaa koodin Batch-osuuden.

@goto(){ :;}

echo "Tässä on Bash-koodia. Loppuun tarvitaan exit."
exit

Alun goto hyppää Batchissa tänne:
:(){ :;}

@echo off
echo Tässä on Batch-koodia.

Tätä kikkailua voi hyödyntää esimerkiksi ohjelman käynnistysskriptiin tilanteessa, jossa sama paketti on suunnattu eri käyttöjärjestelmille. Toinen käyttökohde on puhtaasti Windowsissa: Batch-skriptin voi käynnistää klikkaamalla, ja tämä skripti voi edelleen etsiä ja käynnistää Bash-komentotulkin esimerkiksi MSYS2- tai Cygwin-ympäristössä, eikä tarvita erillistä kooditiedostoa.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta