Comments 63
Сейчас CLI встроен в любую операционную систему, но видеть его использование чаще всего можно в фильмах про хакеров. Для большинства людей работа в интерфейсе командной строки считается «магией», которой владеют лишь "избранные".
Для большинства людей работа в интерфейсе командной строки — переписка с чат-ботами.
$sourceFolder = "C:\Photos"; $destinationFolder = "C:\FilteredPhotos"; $archivePath = "$destinationFolder\PhotosArchive.zip"; Get-ChildItem -Path $sourceFolder -Recurse -File -Include .jpg | Where-Object { $_.Length -gt 2MB -and $_.Length -lt 5MB } | Copy-Item -Destination $destinationFolder -Force; Compress-Archive -Path "$destinationFolder\" -DestinationPath $archivePath -Force; Remove-Item -Path "$destinationFolder\*" -Exclude PhotosArchive.zip -Force
сколько нужно времени чтобы это придумать, отладить? в гуях поставленная задача решается в "пару кликов"
Да, этот пример можно сделать в gui. Тут согласен. Но есть риск человеческого фактора, особенно когда в папке будут тысячи фото. Написание и отладка заняли у меня 3 минуты. Как я написал в статье, если в ide есть любой ai-помошник, то он PowerShell скрипты пишет практически без ошибок. Попробуйте.
Расскажите как вы решите в гуях это парой кликов?
Сортировать по типу, выбрать все jpg, переместить во временную папку. В ней сортировать по размеру, выбрать 2-5 МБ, архивировать. Остальное переместить обратно, временную папку удалить.
P.S. Кстати, насчет замечания автора, что «скрипт не ошибется». Файлы могут быть не только jpg, а еще jpeg или JPG.
Как выбрать по типу в папках рекурсивно? Я ранее видел такие UI, в древнем аналоге explorer от Symantec. В Explorer от Windows есть что-то такое?
Мне кажется что я решаю большинство таких задач через UI, т.к. ни batch ни powershell вот так бегло не знаю, барьер на освоение получается выше чем сделать все ручками. Однако если это повторяемое действие, то скрипт очень быстро окупается. То вы перечислили это совсем не пара кликов.
Я подобное решаю в ТоталКоммандере. Там это делается в пару кликов. И почти всё вышеописанное тоже. Исключение - чистил темповую папку в которой было 5000 подпапок, в которых лежало море файлов (тоже в нескольких папках). Вот тут пришлось PowerShell расчехлять.
А как вы например сделаете такое: есть набор папок (сайтов) в количестве 600 штук (site1, site5, site10, ...). Отдельно есть папка темповая в которой есть для каждого сайта папка с тем же именем, что и основная, но обнаружилось, что они не удяляются при удалении сайтов и там порядка 3000 папок (site1, site2, site3,....). И вот разницу - 2400 папок (site2, site3, site4, site6, ....) надо удалить.
Возможно тоже напишется и довольно быстро на PS, но в ТоталКоммандаре у меня это заняло полминуты. Ну и само удаление да, минут 30.
Исключение - чистил темповую папку в которой было 5000 подпапок, в которых лежало море файлов (тоже в нескольких папках). Вот тут пришлось PowerShell расчехлять.
Перейти проводником в папку, ctrl+a, shift+delete, enter.
Если это HDD, то "Перейти проводником в папку, ctrl+a" может занять больше времени, чем через ps.
Попробовал.... Вижу вот такое - сначала "Preparing do delete from <FolderName>" в течение минут 10. Потом "deleting 12 780 items from <FolderName>" ... speed - 10-100 items/s, Time Remaining - 15 minutes.
Короче - я за то, чтобы не бросаться в крайности. Какие-то вещи в разы удобнее делать в PS, какие-то - в GUI.
Тут дело скорее в том, что PowerShell выглядит убого и неудобно. Это гораздо проще были бы сделать стандартными unix утилитами или bash скриптом.
Про архивацию фоток: если в папке назначения уже есть другие файлы, то они будут удалены...
В графическом интерфейсе каждый файл надо переименовывать отдельно, что долго и муторно.
Правый клик - переименовать с помощью PowerRename (MS PowerToys).
Поиск и удаление пустых папок
Как это вообще сделать в графическом интерфейсе?
Поставить программу для удаления пустых папок? Remove Empty Directories, к примеру.
Поиск в GUI Windows конечно же есть, но мне не нравится скорость его работы и удобство задания условий поиска.
Я тоже не особо люблю встроенный поиск винды, но задавать параметры поиска в форме мне заметно удобней, чем вбивать их в однострочник, надеясь не опечататься.
Скрипт не ошибётся:
Скрипт сделает строго то, что вы в нём написали. А вот вы могли и ошибиться.
Скрипт завершит все процессы, которые используют больше 30% CPU.
Мочить вслепую процессы, даже не оценив, что они делают - плохая практика.
CLI — это не пережиток прошлого, а мощный инструмент, который помогает решать некоторые задачи существенно быстрее и эффективнее, чем если их решать через графический интерфейс.
Это верно. Но графический интерфейс позволяет решать некоторые задачи существенно быстрее, чем командная строка. Потому основное - правильно выбрать инструмент под задачу, а не пытаться всё решить одним только молотком, потому что другой инструмент считаете идеологически неверным.
С последним тезисом полностью согласен. У меня так и написано: "А что, если не выбирать между ними, а научиться пользоваться эффективно обоими?" (в контексте GUI и CLI). Остальные пункты, к ним надо относиться как к примерам. Конечно, для всего этого уже есть утилиты и пр. Но каждая сторонняя утилита - это риск внесения новых уязвимостей в систему, риск словить любой зловред и пр.
"Программа для удаления пустых папок"?😬
Почему у вас в примерах отсутствует форматирование?
Это сделано специально, чтобы вы смогли скопировать скрипт как есть и запустить его у себя. Если бы я оставил форматирование, для его запуска нужно было бы сначала скрипт сохранить в файл, а уже после запускать.
Если бы я оставил форматирование, для его запуска нужно было бы ...
` - вот такую штуку можно нужно использовать в конце строки. Попробуйте закопипастить:
$test_1 = 123; `
$test_2 = 321; `
Write-Host $test_1+$test_2;
Ну и код сразу становится читаемее:
$sourceFolder = "C:\Photos"; `
$destinationFolder = "C:\FilteredPhotos"; `
$archivePath = "$destinationFolder\PhotosArchive.zip"; `
Get-ChildItem -Path $sourceFolder -Recurse -File -Include *.jpg | `
Where-Object { $_.Length -gt 2MB -and $_.Length -lt 5MB } | `
Copy-Item -Destination $destinationFolder -Force;`
Compress-Archive -Path "$destinationFolder\*" -DestinationPath $archivePath -Force; `
Remove-Item -Path "$destinationFolder\*" -Exclude PhotosArchive.zip -Force
80 символов, паровоз из команд, и, в целом, копипастинг-кода без понимания что он делает(а без форматирования хрен пойми что оно там делает), оставим за скобками
Спасибо! Не знал про '
Для написания скриптов для PowerShell больше не нужно знать язык программирования
Ой, то есть оказывается, что всё-таки нужно.
Это же символ экранирования в PS. Базовая фича языка. Это как писать на условном C/C++ и не знать про \
в строках. Вы не уедете далеко без своих собственных базовых знаний, ни один чат-бот вам их не заменит.
Иногда надо посмотреть какие файлы и кем открыты в shared папках на сервере, чтобы закрыть принудительно.
Следующий однострочник выведет список открытых файлов в таблицу Out-GridView, там можно найти и выделить нужные файлы, а затем нажать ОК. В результате выбранные файлы будут принудительно закрыты:
Get-SmbOpenFile|select ClientUserName,ClientComputerName,Path,SessionID| Out-GridView -PassThru –title “Select Open Files”|Close-SmbOpenFile -Confirm:$false -Verbose
PowerShell вообще никак не является эволюцией CMD. Это принципиально другой инструмент, общего у них только то, что взаимодействие с ними осуществляется одинаковым образом.
Это наверное больше риторический вопрос. А так - внутри PowerShell можно команды cmd запускать, имхо - это существенное их общее.
внутри PowerShell можно команды cmd запускать
Не все. Сейчас точно ничего не назову, но не раз попадались команды, которые требуют запуска строго в cmd, а не в ps.
Не то, чтобы команды. Это просто alias-ы. Например, wget это синоним командлета Invoke-WebRequest, а вовсе не вызов соответствующей утилиты. Пользователь может и свои альясы создавать с помощью Set-Alias
Если WSL2 установлен и там есть Линукс - то можно и линуксовые команды вызывать, вроде как.
WSL это WSL - виртуалка внутри которой выполняется всякое. Туда просто очень хорошо маппят ресурсы windows и оно к PoSh вообще никаким местом не относится.
Можете проверить методом выполнения wsl ls -la /mnt/ в cmd и в PoSh - увидите свои диски =)
С тем же успехом можно сделать алиас на ssh <сервер_нейм> bash -c '<команда>' (ну или какие там аргументы у ssh) - было бы желание все настроить.
Не вижу ни малейшего повода для риторизмов :) Любой shell предназначен для запуска внешних программ, но никому не придёт в голову утверждать, что все shell'ы — эволюция sh. Или command.com
У PowerShell принципиально иная идея. Вот прям именно, что принципиально. Что возвращает юзеру или следующей программе в конвейере cmd.exe? Текст. Или мусор :) А что PowerShell? Вот то-то...
В последних виндосах можно ещё миксовать в коммандной строке с линукс командами через wsl.
Ждём статью на тему: LLM через пару лет заменит вашу командную строку и закроет вакансии специалистов по командной строке. И вообще LLM через пару лет заменит все, что выглядит сложно и новому поколению не придётся иметь с этим дело.
Вообще, операции с файлами очень удобно совершать в специально задуманных для этого таких штуках, как файловые менеджеры.
Например, Total Commander.
Массовое переименование - выделить нужное и Ctrl+M
Поиск:

Ну и т.д. Про плагины вообще промолчу.
Поиск и архивацию файлов я бы не стал делать с помощью PowerShell, но он меня недавно сильно выручил, когда надо было в полсотне определенных тимс групп добавить несколько пользователей . Хотя, спасибо Дипсику. Он дал пошаговое руководство и даже решение проблемы, когда PowerShell не подключилось сразу к Тимс. Все заняло около 10 мин. Вручную было бы намного дольше.
Но составлять те скрипты вручную с нуля - увольте.
Идите вы со своим PS.
Сравните
apt install httpd nagios nmon wget zip unzip
и чтото внеразумиткльное
GetUpdateInstal-SystemControl как то так какая оо там хрень.
Простите но не одну строчку PS я не могу вспомнить.
winget?
Ну у баша так-то своих приколов хватает уровня, попробуй без гугла сообрази чем if (()) отличается от [[]] или [] или (), а еще можно попробовать {}
Ну и все же сравнивать название командлетов и название приложений, несколько не корректно. Если уж сравнивать apt то с winget. ip -a с ipconfig /all - и тут не сильно то много отличий.
function chapter {
$link = Get-Clipboard
if (-not $link) { Write-Host "Буфер обмена пуст!" -ForegroundColor Red; return }
$id = $link.Split("/")[-1]
yt-dlp --split-chapters -f bestaudio --extract-audio --audio-format mp3 -o "chapter:%(section_title)s.%(ext)s" $link
Get-ChildItem -File | Where-Object Name -match "\[$id\]" | Remove-Item
Write-Host "Готово!" -ForegroundColor Green
}
если и пользоваться то только какой нибудь ерундой типа этой, из примера с фотками слишком много подводных, из за ошибки которой можно потерять все свои фотографии или иные файлы, еще и отладка долгая
Для написания скриптов для PowerShell больше не нужно знать язык программирования. Используйте ChatGPT, GigaChat, любой чат-бот, которым вы уже наверняка пользуетесь: «Напиши мне однострочный скрипт PowerShell, который…» и чат-бот вам быстро выдаст результат.
Из недавнего:


Нейро от яндекса, может, и не то же самое, что GPT, но доверия у меня не вызывает ни одна из нейросетей. В данном случае — выдана сильно устаревшая информация. В целом предпочитаю искать информацию в более достоверных источниках.
Касательно скриптов (для Windows, Linux — не суть): желательно понимать, что именно делает сценарий, тупо копировать ответ нейросети — так себе вариант.
Скрипт не ошибётся
Выше уже обозначили, что можно ошибиться при написании сценария. Дополню: предварительно проверяю действие сценария (в /tmp, на несущественных файлах).
В Windows многое можно сделать через GUI, но для некоторых операций действительно удобнее использовать свой сценарий. У меня это обычно копирование файлов с присвоением временнОго суффикса.
Ознакомился с тремя частями (1., 2., 3.) . +, +, +. Полезно. Комментарий оставлю только к этой части.
Спасибо за отзыв! Конечно же, все надо делать с головой. Я, кстати, немного обескуражен популярностью именно первой части, т.к. хотел просто показать на каких-то простых примерах, как автоматизировать какие-то простые вещи. Но очевидно, что тема востребована.
Спасибо Вам за статью (статьи).
Насчёт популярности. Не скажу за всех, но для меня консоль в Windows представляется намного более сложной, нежели в Linux. Громоздкий, не интуитивный синтаксис, куча ограничений (по исполняемым файлам) и пр. В Вашей статье нашёл несколько полезных для себя примеров, позже обязательно попробую применить.
Насчёт "показать на каких-то простых примерах ... какие-то простые вещи" — так логично, когда написано просто, многим будет понятно.
Ежели планируете публиковать ещё части лично мне было бы интересно увидеть побольше (в разы) примеров элементарных операций над файлами\папками (именно в Windows).
Публиковаться точно буду, но я, как и вы, судя по всему, больше работаю в Linux ) поэтому, если скажите, какие примеры нужны, что вам интересно, я напишу про это.
Поскольку в Linux мало чего есть с GUI (из нужного мне) пришлось написать некоторое количество сценарий, в частности для синхронизации. Там это оказалось на удивление просто. При том, что не знаю ни одного ЯП.
В Windows же сходу не разобрался.
Интересует:
Присвоение текущей даты-времени к имени файла. Нашёл такой вариант: set CURDATE=%date%
Маска даты YYYYmmdd
%CURDATE:~0,4%%CURDATE:~5,2%%CURDATE:~8,2%
Громоздко и зависит от формата даты в системе.
В статье : $date = Get-Date -Format "yyyyMMdd_HHmmss"
2. Условия существования. В Linux логично:
if [ -d /путь/ ]; then
else
fi
if [ -f /путь/ ]; then
elif
else
fi
И т.п.
3.
echo -e "текст \tтекст \nтекст \n Опять же дата-время в Linux: $(date '+%Y-%m-%d, %A, %H:%M:%S') \n" > /путь/echo
Как это делается в Windows? echo, экранирование Escape-последовательностей.
4.
Аналог в Windows (перенаправление вывода, дозапись в файл):
ls -Rths -lt /путь1 > /путь2
nl /путь2 > /путь3
cat /путь/echo /путь3 > /путь4
Автооткрытие файла в редакторе:
xed /путь4 &
5. Назначение переменных.
В Linux:
Host="Имя машины"
OS="Дистрибутив"
User="Имя пользователя"
Script_name="Имя сценария"
echo -e "Сценарий:\t\t
Host \nОС:\t\t\t\t
User \nДата:\t\t\t$(date '+%Y-%m-%d, %A, %H:%M:%S') \n" > /путь/echo
В Windows есть подобное?
6. Собственно, создание исполняемых файлов.
В Linux всё суть файл, поэтому:
chmod +x /путь_к_любому_файлу_с_любым_расширением_или_без_оного
chmod 774 -c -R /путь_к_папке
В Windows только .bat (в Windows7 не ассоциирована программа), .cmd (запускается cmd с выполнением перехода в папку (cd) выполняемого файла, но сценарий не выполняется), .ps1 (не пробовал)? .exe также не захотело запускаться.
Разумеется, всю эту информацию при желании можно найти. Но. В Linux достаточно было глянуть man по интересующей команде, почитать немного в интернете, потыкать в терминале (с синтаксисом у меня проблемы постоянно) и всё работает. В Windows же отнюдь.
Заранее спасибо.
Что-то все у вас смешалось: cmd и bat это одно, powershell это другое. Первые лучше вообще не трогать, последний уже полноценный язык программирования.
смешалось
В Linux можно через GUI, можно через терминал (эмулятор), можно свои сценарии. Суть вопроса: как сделать свои сценарии в Windows.
И первые (первую половину из первых) я уже трогаю.
И первые (первую половину из первых) я уже трогаю.
Зачем? Не понимаю. Учите powershell, если нужен именно встроенный shell, и будет вам счастье. Если можно поставить стороннее ПО, то вариантов куча: от того же баша до скриптов на питоне и C#.
Зачем?
I. Ещё раз. В Linux уже несколько лет использую самодельные сценарии (bash) для своих нужд. В Windows то же самое (кажется) намного сложнее.
Учите powershell
II. Ежели и начну что учить, так скорее Golang либо Python. Но мне (пока) хватает bash.
поставить стороннее ПО
III. Статья про то, что можно (удобнее) писать самому необходимые сценарии (также см. пункт I.). Для простых вещей (ls, mkdir, cp, df, etc) не вижу смысла ставить целое ПО (GUI?). Ибо: во-первых, самому интересно разобраться, как это работает, во-вторых, графический интерфейс здесь не нужен (медленнее, тяжелее).
IV. Всё ещё пользуюсь Windows 7, там нет WSL, посему sh не представляется возможным установить\использовать. В Windows 10 установил, но предпочёл бы использовать cmd.exe (нативное).
В Windows то же самое (кажется) намного сложнее.
Всегда сложно осваивать что-то новое.
Ежели и начну что учить, так скорее Golang либо Python
Не могу запретить :)
не вижу смысла ставить целое ПО (GUI?)
Не ставьте :)
Всё ещё пользуюсь Windows 7, там нет WSL, посему sh не представляется возможным установить\использовать
Для windows есть bash, не требующий wsl. В частности, он идет в составе git for windows, но можно и отдельно поставить. Ну и насчет win7, вы большой оптимист, если считаете, что там заведутся современные версии go и питона.
насчет win7, вы большой оптимист, если считаете, что там заведутся современные версии go и питона
Не говорил, что собираюсь заводить "современные версии go и питона" в win7. Интересно и небесполезно (в перспективе) знать какой-нибудь ЯП.
И я пессимист.
Для windows есть bash, не требующий wsl
А cmd.exe для чего вообще? Почему-то считал (считаю) это (сильно ограниченным) аналогом эмуляторов терминала в Linux.
Всегда сложно осваивать что-то новое.
Ещё раз. В Linux я буквально методом тыка начал (с нуля) писать работающие (!) сценарии, не зная на тот момент даже, что это называется bash. В Windows — "всё не то и всё не так".
А cmd.exe для чего вообще?
Это старый командный интерпретатор, берущий корни еще в dos. хотите пользоваться современными средствами, берите powershell.
В Windows — "всё не то и всё не так".
Да, в windows все по другому, но сейчас не проблема сделать, чтобы было удобно.
старый командный интерпретатор, берущий корни еще в dos
Ноль развития за 30+ лет?
хотите пользоваться современными средствами, берите powershell
Для ls, mkdir, cp, df, etc (или как они там в Windows называются) cmd не годится? Мне вот нужны только эти (в основном) команды. mkdir, кстати, пользуюсь даже в Windows 7.
И в DOS как-то же работали в командной строке (до появления PowerShell) ?
Ноль развития за 30+ лет?
Ну как ноль? :) Написали замену в виде powershell.
ls
> Get-Command ls
CommandType Name Version Source
----------- ---- ------- ------
Alias ls -> Get-ChildItem
mkdir
> Get-Command mkdir
CommandType Name Version Source
----------- ---- ------- ------
Function mkdir
cp
> Get-Command cp
CommandType Name Version Source
----------- ---- ------- ------
Alias cp -> Copy-Item
df
> Get-Command df
Get-Command: The term 'df' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
> Set-Alias -Name df -Value Get-Volume
> df
DriveLetter FriendlyName FileSystemType DriveType HealthStatus OperationalStatus SizeRemaining Size
----------- ------------ -------------- --------- ------------ ----------------- ------------- ----
Recovery NTFS Fixed Healthy OK 4.10 GB 4.79 GB
C Windows NTFS Fixed Healthy OK 153.1 GB 471.16 GB
FAT32 Fixed Healthy OK 450.57 MB 495 MB
И в DOS как-то же работали в командной строке (до появления PowerShell) ?
В 90-e уже были Norton Commander и Windows 3.1. Мало кто сидел в чистом Досе.
Перенос между операционками страдает, пришлось дополнительно экранировать кавычки с переноса между Windows и MacOS + имя в Windows powershell, а в MacOS ps
Почему командная строка всё ещё актуальна или 5 примеров, как PowerShell может сэкономить вам часы работы