我主要强调的是从/etc/passwd
文件中提取用户名,然后存储在数组列表中我可以逐个显示它,我已经创建了简单的脚本,如下所示
#!/bin/bash
cat "/etc/passwd" > OUTPUT
echo -e $OUTPUT
IFS=:
read -ra ADDR <<< "$OUTPUT"
for i in "${ADDR[@]}"; do
echo -e $i
done
和
的输出> cat /etc/passwd
root:$1$L15vXdMd$SVx9qKAzHtLcqGN8n2SIc.:0:0:root:/:/bin/sh
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/bin/false
super:x:1111:1100:Ldap user:/opt/www/usr/super:/bin/sh
admin:x:1107:1100:Ldap user:/opt/www/usr/admin:/opt/www/jv/bin/cliInit.sh
guest:x:1101:1100:Ldap user:/opt/www/usr/guest:/opt/www/jv/bin/cliInit.sh
postgres:x:1000:1000:Linux User,,,:/home/postgres:/bin/sh
albert:x:1114:1100:Ldap user:/opt/wwwl/usr/albert:/opt/www/jv/bin/cliInit.sh
ritesh112:x:1125:1001:RADIUS user:/opt/www/usr/ritesh112:/opt/dell/mc/bin/cliInit.sh
可能是我在上面的脚本中做了错误的方式(这就是我问这个问题的原因)。根据我的逻辑,首先将/etc/passwd
重定向到(cat "/etc/passwd" > OUTPUT
的任何变量,不知道它是对的或者错误另外,尝试read -ra ADDR <<< "cat /etc/passwd"
但没有工作的替代方案)然后将输出分隔IFS=:
bash变量并将所有用户名存储在数组ADDR
中。
我希望脚本输出如下,sshd
和postgres
用户名除外。
root
super
admin
guest
albert
ritesh112
但是没有任何人有想法吗?
答案 0 :(得分:4)
cat "/etc/passwd" > OUTPUT
不创建变量,只是将/etc/passwd
复制到名为OUTPUT
的文件中。要将内容添加到变量中,您可以尝试OUTPUT=$(cat /etc/passwd)
。
但你可以简单地使用cut:
cut -d: -f1 /etc/passwd
答案 1 :(得分:2)
由于似乎没有其他人像你问的那样把结果放在一个数组中,我会提供这个:
declare -a array=($(awk -F: '!/^sshd|^postgres/{print $1}' /etc/passwd))
echo ${array[1]}
root
echo ${array[2]}
daemon
答案 2 :(得分:1)
有了一点awk,你可以用
达到目标i=0
awk -F: '{ print $1 }' /etc/passwd | egrep -v '^(sshd|postgres)$' |while read; do
array[i]=$REPLY
i=$((i + 1))
done
#output 5th item in array
echo ${array[4]}
#output array length
echo ${#array[*]}
答案 3 :(得分:1)
@perreal已经解释了你的脚本有什么问题。这就是我要做的事情:
cut -d: -f1 /etc/passwd | egrep -v '^(sshd|postgres)$'
说明:
cut
打印输入的字段。 -d:
表示字段与:
分隔,-f1
选择第一个字段。
egrep
进一步过滤cut
的输出。 -v
表示“打印任何不匹配的内容”,正则表达式恰好匹配两个用户名。因此它仍会打印sshd2
或postgresadmin
。
将所有内容放入数组:
declare -a array=($(cut -d: -f1 /etc/passwd | egrep -v '^(sshd|postgres)$'))
(注意:BASH语法;其他shell工作略有不同)。
答案 4 :(得分:1)
不要将输出存储在变量/数组中(在某些情况下你可以得到各种缓冲问题 - 虽然没有使用/ etc / passwd,并且根本没有必要),只需做一些像解析它的行按行或使用awk或cut等工具作为perreal suggested
e.g。
#!/bin/bash
while read -r line; do
echo "${line%%:*}"
done < /etc/passwd
${line%%:*}
将移除与:*
匹配的最长后缀,即包含第一个:
要获取数组,您只需将其更改为(还要注意不包括数组中的postgres
和sshd
。执行此操作的方法数量,但这应该在这里足够好了)
#!/bin/bash
while read -r line; do
[[ "${line%%:*}" != postgres && "${line%%:*}" != sshd ]] && arr+=("${line%%:*}")
done < /etc/passwd
for i in "${arr[@]}"; do
echo -e "$i"
done
或者执行命令替换之类的操作(但同样,在大多数情况下不是最佳实践)
IFS=$'\n'
arr=($(< /etc/passwd))
答案 5 :(得分:1)
您可以尝试以下方式:
declare -a array
i=0
cut -d: -f1 /etc/passwd|egrep -v "^(sshd|postgres)$"|while read; do
array[$i]="$REPLY"
i=$((i + 1))
done
echo "${array[@]}"
或类似的东西:
declare -a array
i=0
while read; do
array[$i]="$REPLY"
i=$((i + 1))
done <<< "$(cut -d: -f1 /etc/passwd|egrep -v '^(sshd|postgres)$')"
echo "${array[@]}"
或者:
declare -a array
i=0
while read; do
array[$i]="$REPLY"
i=$((i + 1))
done < <(cut -d: -f1 /etc/passwd|egrep -v '^(sshd|postgres)$')
echo "${array[@]}"
否则,您也可以使用awk而不是cut
和egrep
(两者):
awk -F":" '($1 != "sshd" && $1 != "postgres"){print $1}' /etc/passwd|while read; do
#...
done