Довольно легко сделать с одним слоем python:
bash-4.3$ tree
.
├── ABC
├── set_pathname_icon.py
├── subdir1
│ ├── file1.abc
│ └── file2.abc
├── subdir2
│ ├── file1.abc
│ └── file2.abc
└── subdir3
└── subdir4
└── file1.txt
4 directories, 7 files
bash-4.3$ python -c 'import os,sys;dirs=[ r for r,s,f in os.walk(".") if r != "."];[os.makedirs(os.path.join(sys.argv[1],i)) for i in dirs]' ~/new_destination
bash-4.3$ tree ~/new_destination
/home/xieerqi/new_destination
├── subdir1
├── subdir2
└── subdir3
└── subdir4
В качестве сценария это можно было бы переписать так:
#!/usr/bin/env python
import os,sys
dirs=[ r for r,s,f in os.walk(".") if r != "."]
for i in dirs:
os.makedirs(os.path.join(sys.argv[1],i))
Воспользуйтесь файловой системой / proc: ваша оболочка bash, поэтому:
shopt -s extglob
stat -c '%U %u' /proc/+([0-9])/ | awk '$2 >= 1000 {print $1}' | sort | uniq -c
Существует более простой подход, который использует опции форматирования ps и AWK
. Мы знаем, что по умолчанию у пользователей-пользователей есть UID, который варьируется от 1000 до 65533 (UID 65534 является пользователем nobody ).
Мы также знаем, что ps имеет флаг форматирования -o, где мы можем выбрать вывод UID, а также процесс. Формат был бы следующим (обратите внимание, что я показываю здесь только 5 первых строк)
ps -eo uid,cmd | head -n 5
UID CMD
0 /sbin/init
0 [kthreadd]
0 [ksoftirqd/0]
0 [kworker/0:0H]
Таким образом, мы можем сделать
ps -eo uid,cmd | awk '$1 >= 1000 && $1 < 65534 '
AWK помогает нам печатать все строки где столбец 1, UID больше или равно 1000 И меньше 635534.
Пример вывода из моей системы (где у меня есть только один пользователь):
$ ps -eo uid,cmd | awk '$1 >= 1000 && $1 < 635534 ' | tail -n 5
1000 /usr/lib/at-spi2-core/at-spi2-registryd --use-gnome-session
1000 /usr/lib/firefox/firefox google.com
1000 ps -eo uid,cmd
1000 awk $1 >= 1000 && $1 < 635534
1000 tail -n 5
EDIT
Я понял, что OP хотел EDIT процессов, используемых человеческими пользователями.
Если все, что вам действительно интересно, это количество процессов, которые принадлежат человеческим пользователям, вот быстрое решение:
ps --no-headers -eo uid,args --sort=uid | awk '$1 >= 1000 && $1 < 65534 {counter++}; END{print counter" human processes"}'
Что касается моего предыдущего решения, я улучшил AWK, которая использует ассоциативные массивы на основе UID, а также добавляет дополнительные флаги в команду ps для включения имени пользователя и сортировки вывода по UID.
ps -eo uid,euser,cmd --sort=uid | awk '$1 >= 1000 && $1 < 65534 { HUMAN++; procTotals[$1]++; if( $1 > UID ) username[$1]=$2; UID=$1 } END{ print "Out of "NR" processes, "HUMAN" belong to human users"; for(i=1000;i<=UID;i++ ) print username[i]":"procTotals[i] }'
Пример выходного сигнала:
xieerqi:$ ps -eo uid,euser,cmd --sort=uid | awk '$1 >= 1000 && $1 < 65534 { HUMAN++; >
Out of 215 processes, 88 belong to human users
xieerqi:84
testuser:4
Для лучшей читаемости, здесь приведен код. Обратите внимание, что часть awk может быть преобразована в скрипт с #!/usr/bin/awk -f shebang line
ps -eo uid,euser,cmd --sort=uid | awk '$1 >= 1000 && $1 < 65534 {
HUMAN++; procTotals[$1]++;
if( $1 > UID ) username[$1]=$2; UID=$1
}
END{ print "Out of "NR" processes, "HUMAN" belong to human users";
for(i=1000;i<=UID;i++ )
print username[i]":"procTotals[i]
}'