这个脚本完成了一半的工作



作为练习,我需要创建一个脚本,它接受2个参数作为输入,

  • <n>一个整数值
  • <path>指向目录
  • 的路径

我需要在路径中创建尽可能多的目录至少有运行<n>进程的用户。这些文件具有<pid>.txt格式,并且必须包含ppid时间,命令

#! /bin/bash
if [ $# -lt 2 ]
then
echo "Hai inserito $#/2 parametri"
echo "<n><path>"
exit 1
fi

if [ "$1" -lt 0 ]
then
echo "errore: Il valore inserito non può essere negativo" 
exit 1
fi

if ! [ -d "$2" ]
then
echo "errore: Il path indicato non è una directory" 
exit 1
fi

OCCURRENCE=$1
PAT=$2

users=($(ps -Af | awk '{print $1}' | sort | uniq ))

for user in "${users[@]}"
do
processes=$(ps -Af | awk -v user="$user" '$1==user'|wc -l)
if [ "$processes" -gt "$OCCURRENCE" ]
then
mkdir $PAT/$user
ps -Af | awk  -v user="$user" -v path="$PAT/$user" '$1=="user" {print $2,$7,$8 >>"$path/"$1".txt" }' 


fi

done

问题是没有创建包含各自目录内内容的文件,而程序只正确创建拥有超过<n>进程的用户的目录。

awk命令有错误吗?有更好的方法来完成这个任务吗?

您的第一个awk过滤器是正确的:$1==user。但第二个是错误的:$1=="user"将第一个字段与字面值字符串user进行比较,而不是与变量user的值进行比较。正如在评论中所指出的,你对"$path"有类似的问题,应该是path(没有$,没有引号)。

还请注意,您应该过滤掉ps输出的第一行,并且,与bash重定向不同,>是连接的,不需要>>

当你使用awk时,这里有另一个完全基于awk的解决方案(用GNUawk测试):

$ ps -Af | awk -v n="$1" -v p="$2" 'NR>1 {
num[$1] += 1
proc[$1][$2 " " $7 " " $8]
}
END {
for(u in num) {
if(num[u] >= n) {
d = p "/" u
system("mkdir -p " d)
for(e in proc[u])
print e > d "/" u ".txt"
}
}
}'

下面的Shellcheck-clean Bash代码演示了执行任务的另一种方法:

#! /bin/bash -p
if (( $# < 2 )); then
echo "Hai inserito $#/2 parametri" >&2
echo "<n><path>" >&2
exit 1
fi
min_proc_count=$1
output_dir=$2
if [[ -z $min_proc_count || $min_proc_count == *[^[:digit:]]* ]]; then
echo 'errore: il valore inserito deve essere un numero positivo' >&2
exit 1
fi
if [[ ! -d $output_dir ]]; then
echo 'errore: Il path indicato non è una directory' >&2
exit 1
fi
ps_output=$(ps -Af --no-headers)
# Get counts of processes for each user
declare -A user_proc_count
while read -r user _; do
user_proc_count[$user]=$(( ${user_proc_count[$user]-0}+1 ))
done <<<"$ps_output"
# Generate per-process output files for users with enough processes
while read -r user pid ppid _ _ _ time cmd; do
(( ${user_proc_count[$user]} < min_proc_count )) && continue
dir=$output_dir/$user
[[ -d $dir ]] || mkdir -v -- "$dir"
printf '%d,%s,%sn' "$ppid" "$time" "$cmd" >"$dir/${pid}.txt"
done <<<"$ps_output"
  • 请参阅正确的Bash和shell脚本变量大写,以解释为什么我使用小写变量名而不是像PATOCCURRENCE这样的ALL_UPPERCASE名称。
  • 看到公认的,优秀的,为什么printf比echo好?来解释为什么我使用printf而不是echo来输出数据。

这是一个基于awk的解决方案,它不需要任何额外的shell级处理,并直接生成必要的输出。

基于我对ps的业余理解,我认为ps -Ao 'uid pid time command'可能更符合他/她的目的。

由于我真正不知道的原因,我只能让它在gawkmawk2上工作,而不是mawk-1nawk

ps -Ao 'uid pid time command' | 
gawk -be '
{
528       ___[_=$!-__]
528   sub(_ "[ t]+","")
528   sub("$",($-__)__,___[_])

} END {
1      sub("^[~][/]",ENVIRON["HOME"]"/",____)
gsub("[/]+",                "/",____)
sub("[/]$",          "",____)
gsub(/47/,"&\&&",____)
1      system(" mkdir -p 47" (____) "47 2>/dev/null")
35      for (_ in ___) {
35          if (+_____ < (gsub(__, "&", ___[_]))) {
5              printf("%s", ___[_]) > (____ "/" _".txt")
}
}
}' _____='THRESHOLD_NUMBER' ____="${DESTINATION_PATH}" __='n'

"$ {DESTINATION_PATH}";后来

total 800
-rw-r--r--  1 501 staff   11709 May 30 11:13 0.txt
-rw-r--r--  1 501 staff     509 May 30 11:13 205.txt
-rw-r--r--  1 501 staff     655 May 30 11:13 262.txt
-rw-r--r--  1 501 staff    1575 May 30 11:13 278.txt
-rw-r--r--  1 501 staff  791516 May 30 11:13 501.txt


296 lines             791,175 utf8 (175 uc)          0.755 MB (      791515)  501.txt
158 lines              11,708 utf8 (0. uc)           0.011 MB (       11708)  0.txt
6 lines                 508 utf8 (0. uc)           0.000 MB (         508)  205.txt
12 lines               1,574 utf8 (0. uc)           0.002 MB (        1574)  278.txt
7 lines                 654 utf8 (0. uc)           0.001 MB (         654)  262.txt

==> 0.txt <==
1   4:36.92 /sbin/launchd
105   1:00.85 /usr/libexec/logd
==> 205.txt <==
148   0:32.10 /usr/libexec/locationd
286   0:00.56 /System/Library/PrivateFrameworks/GeoServices.framewor
==> 262.txt <==
346   0:00.84 /usr/sbin/distnoted agent
365   0:00.06 /System/Library/Frameworks/CoreMediaIO.framework/Versi
==> 278.txt <==
113   0:00.46 /System/Library/PrivateFrameworks/MobileAccessoryUpdat
376   0:00.83 /usr/sbin/distnoted agent
==> 501.txt <==
184   0:01.64 /System/Library/CoreServices/loginwindow.app/Contents/
426   0:22.44 /usr/sbin/distnoted agent

最新更新