Se a saída do seu last
for assim:
username pts/2 1.2.3.4 via Sun Sep 2 06:40 - 06:40 (00:00)
e você deseja adicionar as novas linhas onde elas estavam originalmente, sugiro alterar um pouco a lógica. Leia a entrada linha por linha para começar e divida a linha em palavras somente depois disso. Dessa forma, não há necessidade de procurar explicitamente os parênteses. E você pode repetir todo o loop colocando-o dentro de while true; do ... done
. Então, temos algo assim:
#!/bin/bash
set -f
while true; do
last | while IFS= read -r line; do
for word in $line; do
sleep .1
printf "%s " "$word"
done
echo # prints a newline
done
done
set -f
desativa a expansão de nome de arquivo, o que, de outra forma, possivelmente aconteceria na expansão sem aspas de $line
. Além disso, eu usaria printf
em vez de eco para imprimir as palavras, por várias razões.
Se você quiser explicitamente procurar pelo parêntese de fechamento, poderá usar o [[ .. ]]
test: ele permite a correspondência de padrões com padrões semelhantes a glob, ou com regexes. ( [[ $word =~ $re ]]
seria a correspondência de expressão regular)
#!/bin/bash
set -f
while true; do
for word in $(last); do
sleep .1
printf "%s " "$word"
[[ $word = *')'* ]] && echo
done
done
Embora este, é claro, não adicione uma nova linha nas linhas em que a duração final do login é substituída por algo como still logged in
.
A construção for word in $whatever
tem a desvantagem de tratar vários espaços exatamente como espaços simples, portanto, a saída do script não terá as colunas alinhadas tão perfeitamente quanto no original.