Не подлежит забвению

Вы не находите странным черту освистывать нечто до появления некого более функционального аналога оного и проявлять к этому нечто интерес после? На протяжении всего своего существования командная оболочка Windows неоднократно подвергалась жесткой критике, дескать, ее функциональность оставляет желать лучшего, что, казалось бы, должно было сойти на нет с появлением PowerShell, призванного устранить недочеты первой и упростить жизнь разработчикам и системным администраторам. Нет, PowerShell снискал должную популярность, но появился интерес и к самой командной строке особенно после того, как «селекционерами» были открыты способы запускать командные сценарии как WS[H|F] и HTA. Собственные эксперименты и наблюдения показали, что этим дело не ограничивается.
Некоторые символы в cmd наделены особой логикой, например, двоеточие в начале команды означает метку, а потому если командный сценарий состоит из единственной строки : label или даже одного двоеточия, интерпретатор просто ее проигнорирует; если после двоеточия стоит один из знаков перенаправления потока, сути это также не изменит — интерпретатор по-прежнему будет считать данную строку меткой, что в общем-то логично. Вообще, изменяя порядок использования некоторых спецсимволов командной строки, можно добиться любопытных побочных эффектов, таких как, скажем, запуск PHP кода в виде командного сценария:

:nul php "%~f0" %*
  echo:End
exit /b
*/
echo "\r";

foreach (array_slice($argv, 1, count($argv)) as $i) echo "$i\n";
?>


Или то же, но — bash:

:<nul bash "%~f0" %*
  echo:End
exit /b
EOF
for i in $@;do echo $i;done


Конечно же при этом обыгрываются особенности самих вызываемых интерпретаторов, но основная суть в том, что такое вообще возможно. Возможен также и запуск сценариев Perl, Ruby или Python как командных сценариев в виду наличия у перечисленных интерпретаторов ключа -x, заставляющий последние игнорировать первую строку передаваемого на исполнение кода. Строго говоря, данное утверждение справедливо для Python, а вот Perl и Ruby с данным ключом будут игнорировать все до тех пор, пока не встретят шебанги #! perl и #! ruby соответственно.

Perl:

@echo off
  echo:Start
  2>nul perl -x "%~f0" %*
  echo:End
exit /b
#!perl
foreach my $i (@ARGV) {print $i, "\n";}


Ruby:

@echo off
  echo:Start
  2>nul ruby -x "%~f0" %*
  echo:End
exit /b
#!ruby
ARGV.each do |i| puts i;end


Python:

@echo off&echo:Start&2>nul python3.4m -x "%~f0" %*&echo:End&exit /b
from sys import argv
for i in range(1, len(argv)): print(i)


Подобный подход применим и к PowerShell, а вот утверждать, что описанное выше применимо и к другим интерпретируемым языкам, не стану, могу лишь допустить такую возможность причем с совсем другого ракурса.

© Habrahabr.ru