我正在重写代码以使用较新的系统。我没有编写原始代码,但我尝试使用旧代码作为模板。当我单独运行该命令时,它工作得很好。当我尝试将其作为 shell 中的脚本或函数的一部分运行时,却没有。
#!/bin/bash
function find_user() {
local txt
local user_list
local username
local displayName
echo "Find User"
echo "---------"
echo -n "Enter search text (e.g: lib): "
read txt
if [ -z "$txt" ] || ! validate_fullname "$txt"; then
echo "Search cancelled."
else
echo
user_list="$(samba-tool user list | grep -i ${txt} | sort)"
(
echo "Username Full_Name"
echo "-------- ---------"
# Dev Note: Get the username, then displayName parameter, replacing
# the spaces in displayName with an underscore. Do not need to look
# for a dollar sign anymore, as computers are not listed as "user"
# class objects in AD.
for a in "${user_list[@]}"; do
username=$a
displayName="$(
samba-tool user show ${a} | grep 'displayName:' | \
awk -F: '{gsub(/^[ \t]+/,"""",$2); gsub(/ ./,""_"",$3); print $2}' | \
tr ' ' '_')"
echo "${username} ${displayName}"
done
)| column -t
fi
}
当我尝试运行它并输入该find_user
函数时,它会提示输入搜索文本(即我可以输入js
)并按 Enter。
我的问题与该部分有关$displayName=
。在脚本中运行时似乎会生成一个空字符串。如果我从终端手动运行该命令(例如,填写jsmith
作为 的替代${a}
),它会正确输出全名。
我的系统正在运行 bash。
这是怎么回事?我该如何解决这个问题?
答案1
问题是user_list
作为数组访问
for a in "${user_list[@]}"
但设置为字符串:
user_list="$(samba-tool user list | grep -i ${txt} | sort)"
相反你需要
IFS=$'\n' # split on newline characters
set -o noglob # disable globbing
# assign the users to the array using the split+glob operator
# (implicitly invoked in bash when you leave a command substitution
# unquoted in list context):
user_list=( $(samba-tool user list | grep -ie "${txt}" | sort) )
或者更好(尽管bash
具体):
readarray -t user_list < <(samba-tool user list)
(请注意,如果有的话,将为输入的每个空行创建一个空元素,这与 split+glob 方法相反,后者会丢弃空行)。