Se você quisesse que a mensagem fosse lida como uma linha de stdin (digitada pelo usuário quando o script é usado em um terminal) e depois passada como argumento para a função, você poderia fazer:
fct1 "$(line)"
line não é mais um comando padrão, mas ainda bastante difundido. Você poderia substituí-lo por head -n1 , mas com algumas implementações, ele poderia ler mais de uma linha (embora ela produza apenas uma) quando a entrada não estiver vindo de um dispositivo terminal.
Com bash read , você teria que armazená-lo em uma variável. É para isso que read armazena a entrada em uma variável.
IFS= read -r line && fct1 "$line"
Com zsh , você pode usar a opção read que ecoa os dados lidos em vez de armazená-los em uma variável, então -e acima pode ser escrito lá como line :
fct1 "$(IFS= read -re)"
(isso é menos eficiente do que usar IFS= read -re com uma variável, pois precisamos separar um processo para que o zsh possa ler a saída de read ).
Claro, você também pode substituir seu:
local msg1=${@}
com
local msg1; IFS= read -r msg1 || return