这是我的bash函数,用于获取命令输出作为参数,然后返回输出行数组。
function get_lines {
while read -r line; do
echo $line
done <<< $1
}
SESSIONS=`loginctl list-sessions`
get_lines "$SESSIONS"
loginctl list-sessions
的实际输出为:
SESSION UID USER SEAT
c2 1000 asif seat0
c7 1002 sadia seat0
但是while循环仅在一行打印所有输出时运行。如何获得一系列行并将其返回?
答案 0 :(得分:2)
您可以使用readarray并避免使用get_lines函数:
readarray SESSIONS < <(loginctl --no-legend list-sessions)
这将创建数组SESSIONS
,并将命令输出的每一行映射到数组的元素。
答案 1 :(得分:1)
这个答案的价值在于解释OP代码的问题
- 其他答案显示使用 Bash v4 + 内置mapfile
(或其有效别名,readarray
)来直接读取数组元素中的输入,而不是需要自定义shell功能。
- 在 Bash v3.x 中,您可以使用IFS=$'\n' read -r -d '' -a lines < <(...),
,但请注意,将忽略空行。
您的主要问题是未加引号(非双引号)使用$1
会使shell将word-splitting应用于其内容,从而有效地规范化所有空白行 - 包括换行符 - 每个单独的空格,导致while
循环的单输入行。
其次,使用$input
取消加引号会在echo
的输出上再次应用此分词。
最后,使用read
而不设置$IFS
,内部字段分隔符,空字符串 - 通过IFS= read -r line
- 从每个输入行修剪前导和尾随空格。
也就是说,你可以简化你的函数直接从stdin读取而不是参数:
function get_lines {
while IFS= read -r line; do
printf '%s\n' "$line"
done
}
然后您可以使用process substitution:
按如下方式调用get_lines < <(loginctl list-sessions)
使用管道也可以,但get_lines
将在子shell 中运行,这意味着它无法设置当前可见的变量壳:
loginctl list-sessions | get_lines
答案 2 :(得分:1)
这是bash
v4 +中的一种方式:
SESSIONS=`loginctl list-sessions`
mapfile -t myArray <<< "$SESSIONS"
REF: