LINUX.ORG.RU
ФорумAdmin

PowerShell на работе и в быту

 , ,


0

1

Если под Линукс есть PowerShell, можно попробовать сделать с ним что-нибудь полезное. Какой аналог у команды ps aux | awk '$1 !~ /root/ {print $0}'?

ps aux | sed -E 's/ +/\t/g' | ConvertFrom-Csv -Delimiter "‛t" | ? -Property {user} -ne root
Данный код выдаст все объекты (процессы), у которых пользователь не является root. Средствами самого повершелла команда должна была быть выглядеть как Get-Process -IncludeUserName | ? -Property username -ne root.

Обращение к sed'у можно заменить тоже повершелловскими средствами. Тогда команда приобретёт вид

ps aux | % {$_ -replace " +","‛t"} | ConvertFrom-Csv -Delimiter "‛t" | ? -Property {user} -ne root

Действияя проводились под PowerShell 7 на Debian 10.

Ответ на: комментарий от Siborgium

PowerShell нормально раскрывается только на винде за счет объектов вместо текста.

Под линукс тоже нормально раскрывается за счет объектов.

 $ (gps -id $pid).Gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    Process                                  System.ComponentModel.Component

anonymous ()

Какое упоротое многословие. И я вообще не понимаю кем надо быть чтобы пришло в голову это использовать для однострочников.

На линуксе это ваше вендузятное убожество никогда не взлетит, успокойтесь уже. Даже питон в качестве шелла только упоротые питонисты используют, причём питон на несколько порядков круче и удобнее чем поверщель. Ща вам WSL допилят вот там и будете развлекаться, пихать всякое в свою щель.

Stanson ★★★★★ ()
Последнее исправление: Stanson (всего исправлений: 2)
Ответ на: комментарий от Stanson

Упоротые только те, кто не понимает что для работы в шелле все это многословие легко заменяется алиасами (существующие можно посмотреть в Alias:, там же можно добавить новые). Шелл так же не чувствителен к регистру и даже если для ключей-параметров команд не заданы короткие алиасы (а для многих команд во втроенных модулях они заданы) - их все равно можно сокращать, например -InputObject можно сократить до -in если нет других параметров начинающихся с -in. Для ForEach-Object и Where-Object существуют короткие варианты которые не требуют блоков кода и встроенные алиасы % и ? соответственно. Так что можно писать однострочники в шелле без проблем. А вот в скриптах нормальные полные имена команд и работа с объектами читается куда лучше чем традиционные шелл-скрипты.

anonymous ()
Ответ на: комментарий от anonymous

У gps есть фатальный недостаток - он не показывает процент CPU. То есть ps aux | awk '$3 > 0' я не сделаю. Меня этот вопрос волнует. В интернете есть способы вызвать процент использования процессора, но они заточены чисто под Windows.

gedisdone ★★★ ()
Ответ на: удаленный комментарий

у меня это главный инструмент, которым я пользуюсь каждый день

И что ты забыл на ЛОРе? Вали на винфак и пердолься там с соперрдольниками своими в поверщель, сюда-то эту невменяшку зачем тащить? Здесь это никому кроме таких же вендузятников не интересно.

Stanson ★★★★★ ()
Ответ на: комментарий от gedisdone

Необходим именно % CPU? Тогда да, просто так не получится, нужно высчитывать, но там есть св-во CPU которое в секундах показывает сколько процесс использовал все CPU.

anonymous ()
Ответ на: комментарий от anonymous

У ps нет возможности выдать результат как CSV, поэтому приходится городить конструкцию % {$_ -replace " +","‛t"}. В FreeBSD есть возможность через libxo выдать JSON или XML, но здесь о таком думать не приходится.

gedisdone ★★★ ()
Ответ на: комментарий от gedisdone

дык ps и не задумывался как мегакомбайн, для этого есть пайпы и другие утилиты,которые выведут тебе json,csv или совсем какую-нибудь экзотику

anonymous ()
ps aux | % {$_ -replace " +","`t"} | ConvertFrom-Csv -Delimiter "`t" | ? { [Float]$_.'%MEM' -gt 0.0 }

Таким образом можно вычленить процессы с потреблением памяти больше нуля. Есть модуль Crescendo, который позволяет сделать обвязку в формате JSON командам для использования в PowerShell с объектами и прочими прелестями.

gedisdone ★★★ ()

Был подготовлен модуль для Crescendo.

{
    "$schema" : "./Microsoft.PowerShell.Crescendo.Schema.json",
    "Verb" : "Invoke",
    "Noun": "ps",
    "OriginalName": "/usr/bin/ps",
    "OriginalCommandElements": [
    "aux"
    ],
    "OutputHandlers": [
    {
    "ParameterSetName": "Default",
    "Handler":" param ( $psoutput )
                #$CSV = $psoutput | % {$_ -replace \"([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +(.*)\",\"${1}`t${2}`t${3}`t${4}`t${5}`t${6}`t${7}`t${8}`t${9}`t${10}`t${11}\" } | ConvertFrom-CSV -Delimiter \"`t\"
                $CSV = $psoutput | % {$_ -replace \" +\",\"`t\" } | ConvertFrom-CSV -Delimiter \"`t\"
                $PSList = [System.Collections.ArrayList]::new()
                foreach ($line in $CSV) {
                    $PSList.Add([pscustomobject]@{
                    User = $line.'USER'
                    PID = [int]$line.'PID'
                    CPUUsage = [float]$line.'%CPU'
                    MemUsage = [float]$line.'%MEM'
                    VSZ = [int]$line.'VSZ'
                    RSS = [int]$line.'RSS'
                    TTY = $line.'TTY'
                    Stat = $line.'Stat'
                    Start = $line.'START'
                    Time = $line.'TIME'
                    Command = $line.'COMMAND'
                    })
                    #Write-Host $line.'USER'
                }
                $PSList
                "
            }
        ]
}

Запускается и импортируется модуль командой

Export-CrescendoModule -ConfigurationFile ./ps.Crescendo.json -ModuleName ps.psm1 ; Import-Module ./ps.psm1
После этого можно вызывать команду Invoke-ps, которая выдаст объекты процессов. Из нерешённого - как разделить правильно вывод ps. Опции команд не записываются. Была попытка разделить регексом на 11 полей, но она по какой-то причине не получилась. Код с регексом закомментирован.

gedisdone ★★★ ()

Я нейтрален, но выглядит как то убого. Тупое многословие, семантика от юродивого, может на винде норм в виде именно скриптов, но для однострочников которые тут все как жонглёры делают на башах/дашах по бырому это вообще не годится.

А записи вида ConvertFrom-Csv вообще край. Даже поделка поттеринга выбешивает типа NertworkManager и алиасить строго рекомендуется если уж оно есть. А тут. В скриптах может оно и нормально, но как шелл хтьфу и растереть. Да и зачем? баши/даши/zsh и прочие, на голову удобнее, продуманее, проверенны временем. А наборы утили в среднем имеют общий подход к использованию и всё более менее притёрто.

anonymous ()
Ответ на: комментарий от anonymous

Нашёлся лучший вариант.

{
    "$schema" : "./Microsoft.PowerShell.Crescendo.Schema.json",
    "Verb" : "Invoke",
    "Noun": "ps",
    "OriginalName": "/usr/bin/ps",
    "OriginalCommandElements": [
    "aux"
    ],
    "OutputHandlers": [
    {
    "ParameterSetName": "Default",
    "Handler":" param ( $psoutput )
                $CSV = $psoutput | % {[void]($_ -match \"([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +(.*)\"); $matches[1..11] -join \"`t\" } | ConvertFrom-CSV -Delimiter \"`t\" -Header @('USER','PID','%CPU','%MEM','VSZ','RSS','TTY','Stat','START','TIME','COMMAND')
                $PSList = [System.Collections.ArrayList]::new()
                foreach ($line in $CSV) {
                    $PSList.Add([pscustomobject]@{
                    User = $line.'USER'
                    PID = [int]$line.'PID'
                    CPUUsage = [float]$line.'%CPU'
                    MemUsage = [float]$line.'%MEM'
                    VSZ = [int]$line.'VSZ'
                    RSS = [int]$line.'RSS'
                    TTY = $line.'TTY'
                    Stat = $line.'Stat'
                    Start = $line.'START'
                    Time = $line.'TIME'
                    Command = $line.'COMMAND'
                    })
                }
                $PSList
                "
            }
        ]
}
-replace заменили на -match

gedisdone ★★★ ()
Ответ на: комментарий от gedisdone

-replace заменили на -match

Как-то вы переусложнили.

$procs = ($ps = (ps aux))[1..($ps.Count - 1)]
$result =
foreach ($proc in $procs) {
    $user,$id,$cpu,$mem,$vir,$rss,$tty,$stat,$start,$time,$com = $proc -split '\s+',11
    [pscustomobject] @{
        USER = $user
        PID = [int] $id
        CPU = [float] $cpu
        MEM = [float] $mem
        VSZ = [int64] $vir
        RSS = [int64] $rss
        TTY = $tty
        STAT = $stat
        START = $start
        TIME = $time
        COMMAND = $com
    }
}
$result[-1]
$result | Format-Table PID,COMMAND
anonymous ()
Ответ на: комментарий от anonymous

потому что выдает кроме прочего кучу бесполезной иформации. Минимум 50%

Лишней информации не бывает. Объект на то и объект, чтобы с него брать нужное под задачу. Сегодня не нужно, а завтра нужно. Например получить объект родительского процесса для pwsh и убить его:

((gps -id $pid).Parent).kill()
anonymous ()
Ответ на: комментарий от eco_dd

А по нашему будет просто

kill $(pgrep process)

Это не убивает родительский процесс. Например mc запущен в консоли, надо убить консоль.

(gps mc).Parent.kill()
anonymous ()
Ответ на: комментарий от anonymous

pwsh не отменяет bash.

только показывает насколько поделка мелких хуже того, что существует в линуксе давным давно. Да это еще ничего. Вот когда читаешь более-менее сложный скрипт, да еще с уродской ВеРбЛюЖьей НоТаЦией с сокращениями - вообще без поллитры не обойдешься. Чувствуется, что разрабы выкурили не один косяк пока сочиняли нечто «лучше чем линуксе»

anonymous ()
Ответ на: комментарий от anc

Падумаешь всего-то переписать под что-то другое.

Я ничего не пишу, скрипты для себя не в счет. pwsh всегда открыта, это моё любимое приложение, что под линуксом, что под виндой, во многом они совместимы (больше чем с Windows PowerShell), за исключением ОС-ориентированных особенностей.

anonymous ()
Ответ на: комментарий от anonymous

Я ничего не пишу,
pwsh всегда открыта, это моё любимое приложение

Эмм, любите просто смотреть на неё? Или всё гораздо серьезнее и подобные отклонения на других ресурсах обсуждают?

anc ★★★★★ ()
Ответ на: комментарий от anonymous

Вот когда читаешь более-менее сложный скрипт, да еще с уродской ВеРбЛюЖьей НоТаЦией с сокращениями - вообще без поллитры не обойдешься.

Это наследственное. Всё winapi это «без полллитры никак или что курил индус?».

anc ★★★★★ ()
Ответ на: комментарий от anonymous

Я нейтрален, но выглядит как то убого. Тупое многословие

Что поделать, M$. При всей убогости pwsh идея за ним на голову выше текстовых шеллов.

продуманее

Мертвому припарки.

Siborgium ★★★ ()
Ответ на: комментарий от Siborgium

При всей убогости pwsh

И чем же она хуже bash? Практически те же сочетания клавишь, поиск, полная совместимость с линукс-окружением – запускается все, что и в bash, одинаковая скорость работы, подсветка синтаксиса, полная кастомизация промпта, выбор рабочей парадигмы – хочешь используй внешние утилиты, хочешь внутренние, хочешь .Net-методы, хочешь все вместе.

anonymous ()
Ответ на: комментарий от eco_dd

При чем тут подсветка и скорость?

Потому, что это шелл прежде всего.

в этом случае надо сравнивать возможности интерпретатора и удобство синтаксиса.

Чем отличается cat file в bash и в pwsh? Oтличия начинаются тогда, когда ты хочешь, например обработать вывод этой команды – ты можешь это сделать через утилиты, а можешь через возможности pwsh.

cat file | grep 'string' # через grep
cat file | sls 'string'  # через Select-String

Но во втором случае получаем не просто строку, а объект со своими методами и свойствами:

 $ cat file | sls 'string' | gm

   TypeName: Microsoft.PowerShell.Commands.MatchInfo

Name               MemberType Definition
----               ---------- ----------
Equals             Method     bool Equals(System.Object obj)
GetHashCode        Method     int GetHashCode()
GetType            Method     type GetType()
RelativePath       Method     string RelativePath(string directory)
ToEmphasizedString Method     string ToEmphasizedString(string directory)
ToString           Method     string ToString(), string ToString(string directory)
Context            Property   Microsoft.PowerShell.Commands.MatchInfoContext Context {get;set;}
Filename           Property   string Filename {get;}
IgnoreCase         Property   bool IgnoreCase {get;set;}
Line               Property   string Line {get;set;}
LineNumber         Property   int LineNumber {get;set;}
Matches            Property   System.Text.RegularExpressions.Match[] Matches {get;set;}
Path               Property   string Path {get;set;}
Pattern            Property   string Pattern {get;set;}

Все зависит от того, чего надо. Понятное дело, что sudo pacman -Suy одинаково работает и в bash и в pwsh

anonymous ()