7 заметок с тегом

powershell

Uptime в Windows (на Powershell)

Написал на PowerShell скромный аналог утилиты uptime из Линукса (эта утилита показывает сколько дней компьютер работает без перезагрузки):

[math]::round(((Get-Date) - ($os=gwmi Win32_OperatingSystem).ConvertToDateTime($os.lastbootuptime)).TotalDays, 2)

В основном в сети предлагается запустить «net stats srv» и посмотреть строку «статистика после» («statistics since»), впрочем и вариантов на PowerShell тоже хватает. Кстати, можно сделать ещё и такой вариант:

[math]::round(((Get-Date) - (((net stats srv)[3] -split ' ')[2,3] -join ' ' | Get-Date)).TotalDays, 2)

Почти LISP. И всё-таки мне очень нравится PowerShell.

Optkit: можно ли автоматизировать мою графику?

optkit (18.68КиБ)

Выкладываю optkit — программу (написана на PowerShell v1, это значит — под Windows), которая определяет можно ли оптимизировать графику в форматах PNG, GIF, JPEG в указанной папке. При запуске нужно указать папку.

Примерный вывод есть на скриншоте. Выводится сколько удалось сэкономить, для GIF выводится сколько они будут занимать в PNG (если это даст экономию).

Программа использует ряд других программ, которые должны лежать в папке utils, это:

  • SuperGIF 1.5 (должен быть «купленным»)
  • GIFLite (можно поискать FTP-поиском), утилита не используется для 64-битных ОС
  • jpegtran
  • optipng
  • pngout (нужна command line версия)
    Моя программа не использует никаких продвинутых техник (например, не пытается избавиться от прозрачных, но не одноцветных участков), может ещё руки дойдут и сделаю.

Дополнено: Харисов подсказывается, что на Bash есть инструмент интереснее — imgcomp и писался явно не пару вечеров, как мой. Кстати, сравнивая две программы (на Bash и PowerShell) можно сделать интересные выводы о читаемости этих языков и их мощности.

Epic War 4

EpicWar4 (51.74КиБ)

Подсел на флеш-игрушку Epic War 4.

Но медленно наращивать мощность очень уж скучно, сделал патч, который увеличивает количество денег до двух миллионов, применив его 2-3 раза, можно купить всё что только есть в игре.

Для того, чтобы применить патч, найдите SOL-файл игры (где такие файлы обычно лежат в разных операционных системах можно посмотреть в «Википедии») — там содержится её сохранённое состояние. И укажите программе при запуске полный путь и имя этого файла.

Программа написана сразу на трёх языках — PowerShell (для Windows) и PHP с Python (для всех), запускайте любым из этих трёх интерпретаторов:

#!/usr/bin/env python
########################################################
# Written by Evgeny Stepanischev (//bolknote.ru)  #
# Epic War 4 money patch (for PowerShell, Python, PHP)  #
#<?/*
"""*/
echo str_repeat('#', 55), chr(10);

if ($_SERVER['argc'] > 1) {
    
    $fp = @fopen($_SERVER['argv'][1], 'r+b');
    if ($fp) {
        $content = fread($fp, 655350);
        $content = preg_replace('/(?<=stat_money).{5}/s', pack('H*', '0480C584B4'), $content);

        rewind($fp);
        fwrite($fp, $content);
        echo 'Done.';
    } else {
        echo 'Invalid file.';
    } 

    fclose($fp);
} else {
    echo 'Usage: ', $_SERVER['argv'][0], '<filename>';
}

__halt_compiler();

""" + """ " | out-null

If ($args) {
    [char[]] $binary = Get-Content -encoding byte $args[0]

    $binary = [string]::join('', $binary) -replace`
              'stat_money.{5}', `
              "stat_money$([char]0x4)$([char]0x80)$([char]0xC5)$([char]0x84)$([char]0xB4)"

    Set-Content $args[0] ([byte[]][char[]] $binary) -encoding byte

    "Done."

} Else {
    "Usage: " + $MyInvocation.MyCommand.Name +" <filename>"
}

"""
from sys import argv
from os.path import basename

if len(argv) > 1:
    name = 'stat_money'

    f = open(argv[1], 'r+b')
    binary = bytearray(f.read())

    try:
        index = binary.index(name) + 1 + len(name)
        binary[index:index+4] = '\x80\xc5\x84\xb4'

        f.seek(0)
        f.write(binary)
        f.close()
        print('Done.')
    except:
        print('Invalid file.')
else:
    print('Usage: %s <filename>' % basename(argv[0]))

# " | out-null

python patch.ps1 DEF4_SAVE.sol или powershell -Command .\patch.ps1 DEF4_SAVE.sol или php patch.ps1 DEF4_SAVE.sol

Жаль расцветить три языка в одном файле можно только вручную.

Как получить короткое имя в Powershell (8.3)

Надо постепенно переходить на Powershell V2. Там многие вещи делаются сильно проще, чем в первой версии, да и язык сильно богаче. Вот так, например, можно получить короткое (DOS 8.3) имя в первой версии Powershell:

(New-Object -ComObject Scripting.FileSystemObject).GetFile($filename).ShortPath

Это не единственный способ (например, можно сформировать запрос к WMI), но остальные не проще, в V2 это делается так:

Get-Shortpath $filename

Таких примеров — множество: управление фоновыми задачами, работа с временными файлами и так далее.

 2 комментария    10   2010   powershell

«Гопник» и «Гопник-2»

На «PyCamp Kyiv», на тех немногочисленных докладах, которые мне были не интересны, играл в текстовые игры «Гопник» и «Гопник-2». Наверное многим они известны. Если нет,то поиграйте, забавно. Так как в интернетах я с огромным трудом нашёл вторую часть, то попробую наводнить эту заметку ключевыми словами.

Действие первого «Гопника» (автор — V.P, июнь 2003-го, язык — Turbo Pascal) происходит в Новосибирске, сюжет — вы вылетаете из университета и попадаете на улицу, у есть вас выбор какую «специальность» освоить — пацан, отморозок, гопник или вор. У каждой «профессии» свои плюсы (хотя, кажется, проходить проще всего вором): у «пацана» есть девушка и его сразу пускают в клуб, на «отморозке» всё заживает, как на собаке, «гопник» свой в притоне, а «вор» на короткой ноге с барыгами и, как следует из названия, хорошо умеет воровать.

Вам придётся (в текстовом режиме) шататься по окрестностям, воровать, покупать и продавать, ходит в качалку и клуб и так далее, а в конце — разобраться с ректором.

Доступны несколько «локаций» (некоторые открываются не сразу, а после каких-то действий): «базар» (тут можно купить шмотки и еду, а так же воровать кошельки), «больница» (тут поправляют здоровье и лечат переломы), «подруга» (поправляет здоровье), «притон» (тут тусуются пацаны, которые смогут за тебя врубится, если что), «клуб» (можно играть на деньги), «качалка» (улучшение бойцовских навыков) и «барыги» (это «чёрный рынок», им можно продать свой хлам или купить полезного).

В течение игры нужно не забывать прокачивать характеристики: силу (увеличивает урон, даёт больше здоровья), ловкость (увеличивает шансы попасть по противнику), живучесть (так же увеличивает здоровье) и удачу (чем больше удача, тем успешнее воруешь и реже влипаешь в различные неприятности).

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

Гопник (30.01КиБ)

Сюжет второй части «Гопника», «Гопник-2 „Покорение культурной столицы“» (автор другой — d-maxx, из Сургута, ≈2005-й год, использован Turbo C++ 3.00): вы из Новосибирска отправляетесь в Санкт-Петербург поступать в университет, вам это с трудом удаётся, но через какое-то время вас выгоняют из общаги на улицу за постоянные пьянки и нарушение общественного порядки.

На улице надо выбирать, кем вы будете: «потсан» (есть девушка), «отморозок» (пускают качалку на Петроградской), «гопник» (разводит лохов на деньги) и «нефор» (бесплатно проходит в клуб на Сенной).

Игра несколько отличается от первой части, но самые большие отличия — есть метро, на котором можно ездить в другие районы города, а так же возможность сохраняться и загружаться. Кстати, сохраняться можно только 60 раз, небольшой намёк — счётчик расположен в 68-м (считая с нуля) байте файла сохранённой игры.

Впрочем, вот вам небольшая строка, которая работает в Windows NT/2000/XP/Vista, которая установит счётчик в значение 255:

CMD /C "(ECHO e144 ff && ECHO w && ECHO q) | DEBUG GOP2_1.SAV > nul"

Для Windows 7, из которой, оказывается, удалили утилиту DEBUG, я команды написал на PowerShell (в каталоге, где расположен файл сохранения нужно запустить powershell и выполнить следующие команды):

$var=Get-Content -Encoding Byte gop2_1.sav
[byte[]]($var[0..67] + 255 + $var[69..134]) | Set-Content gop2_1.sav -Encoding Byte

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

Файл читается в переменную $var, читается побайтово как массив чисел. Далее я формирую массив из элеметов с нуля до 67, значения 255 и элементов с 69 до 134-го.

Получившийся массив разношерстных элементов (добавленное мною число «255» имеет тип Int32, остальные — byte) преобразуется к типу «массив байт» и записывается в тот же файл. Set-Content преобразует эти данные в бинарный вид, он знает как их трактовать, так как я явно задал это в параметре.

Так как мне хотелось продемонстрировать как происходит добавление элемента к массиву, преобразование типа массива и передача его по конвееру, я не стал заменять значение одного элемента, что было бы проще и нагляднее.

 31 комментарий    634   2010   powershell   игра

Powershell и объектный pipe

Я задумался над тем, чтобы показать как могла бы выглядеть обработка логов на PowerShell. Как я уже говорил, pipe в PowerShell объектный, то есть по нему идёт не монолитный текст, а набор объектов. Вот я и попробую на примере показать что это.

Для начала настроим лог Apache так, чтобы его было удобнее парсить. К примеру, можно ввести символы табуляций — в логе они не встречаются и вполне подходят на роль разделителя:

LogFormat "%h\t%l\t%u\t%t\t\"%r\"\t%>s\t%b" common
CustomLog logs/access.log common

В логе у нас есть: хост клиента, его ident, имя пользователя (если была произведена HTTP-авторизация), дата и время запроса, метод-URL-версия-HTTP (одним полем), код ответа и длина отданного клиенту контента:

127.0.0.1   -   -   [03/Jan/2010:16:35:30 +0300]    "GET /favicon.ico HTTP/1.1" 404 1976
127.0.0.1   -   -   [03/Jan/2010:16:35:32 +0300]    "GET /a.html HTTP/1.1"  200 521
127.0.0.1   -   -   [03/Jan/2010:16:35:33 +0300]    "GET /favicon.ico HTTP/1.1" 404 1976

Предположим, наша задача — разобрать лог, отобрать только те запросы, у которых код ответа 200, отсортировать по размеру контента и вывести в табличном виде название метода, URL и размер контента.

cat access.log | %`
{
    $o = "" | Select-Object host, logname, user, date, url, code, len, method
    $o.host, $o.logname, $o.user, $o.date, $o.url, $o.code, $o.len = $_.Split("`t")

    [datetime]$o.date = $o.date -replace '^.([^:]+):(.+).$', '$1 $2'
    
    "logname", "user", "len" | %{ If ($o.$_ -eq '-') { $o.$_ = $false } }

    $o.method, $o.url = $o.url.SubString(1).Split()[0..1]

    $o
} | ?{ $_.code -eq 200 } | Sort-Object -property len | Format-Table method, url, len

Итак, что здесь происходит. Читаем лог, проходимся по каждой его строке (%{ }), внутри цикла странным хаком с Select-Object создаём объект с заданными полями, разбиваем входную строку по символу табуляция, убираем у поля «date» первый и последний символы (там квадратные скобки) и двоеточие между датой и временем (такой формат понимает PowerShell), сразу преобразуем это значение в тип «datetime», у поле «logname», «user», «len» заменяем значение на False, если там «-» («пусто» в терминах лога Apache), поле «url» разделяем пробелу (там три значения — метод, URL и версия протокола), избавляемся от окаймляющих кавычек и записываем в соответствующие поля.

Последней строкой цикла выводим получившийся объект. До цикла по pipe шли объекты попроще — всего лишь наборы строк («System.String»), теперь идут более интересные объекты («System.Management.Automation.PSCustomObject» с заданными нами полями).

Из этих объектов мы вибираем только те, у которых поле «code» содержит значение 200 («?{}» — это короткий алиас «Where-Object»), сортируем по полю длины контента и выводим, форматируя в таблицу, три поля: метод запрос, URL и длину контента. На экране будет что-то подобное:

method                     url                        len
------                     ---                        ---
GET                        /                          4701
GET                        /                          4701
GET                        /                          4701
GET                        /                          4701
GET                        /a.html                    521
GET                        /a.html                    521

Надо будет после праздников взглянуть на PowerShell 2.0, говорят, там очень много нового и интересного добавили.

Ещё о PowerShell

Всё-таки PowerShell прекрасен. Вот это вот:

cat user-agents.log | sort -u

одинаково работает и под bash и под PowerShell! Конечно, более «чистый» PowerShell выглядит как на листинге ниже:

Get-Content user-agents.log | Sort-Object -unique

Команда «Get-Content» имеет алиас «cat», «Sort-Object» — «sort», а ключ «unique» сокращается до «u».

Или вот, на bash не совсем похоже, но что проиходит догадаться просто:

ls | where {!$_.length} | %{rm $_}