I am trying to make ffcast screen casting tool bash 4.1 backwards compatible.
and in this ffcast.bash script, there is oneline
shopt -s extglob lastpipe
lastpipe option is only available after bash 4.3, what can I do to emulate its effect?
The #! line in a shell script will be the first thing the command interpreter (sh or bash) sees. Since this line begins with a #, it will be correctly interpreted as a comment when the command interpreter finally executes the script. The line has already served its purpose - calling the command interpreter.
A pipe in Bash takes the standard output of one process and passes it as standard input into another process. Bash scripts support positional arguments that can be passed in at the command line. Guiding principle #1: Commands executed in Bash receive their standard input from the process that starts them.
$( command ) or. ` command ` Bash performs the expansion by executing command in a subshell environment and replacing the command substitution with the standard output of the command, with any trailing newlines deleted. Embedded newlines are not deleted, but they may be removed during word splitting.
Bash reads input from the terminal when interactive, and from the script file specified as an argument otherwise. When interactive, bash allows the user to edit command lines as they are typed in, using familiar key sequences and editing commands similar to the Unix emacs and vi editors.
lastpipe
(introduced in bash 4.2, by the way) can only be simulated by not using a pipe. You need to explicitly run the last command of the pipe line in the current shell, and redirect its input from either a process substitution
# foo | bar | baz becomes ...
baz < <(foo | bar)
or a named pipe (which is POSIX-compliant as well)
# foo | bar | baz becomes ...
mkfifo baz_input
foo | bar > baz_input &
baz < baz_input
Usual behavior without lastpipe
and with job control enabled is to run each element of the pipeline in a sub-shell.
echo asd | var=$(cat) ; echo $var
var
contains nothing, but user may expect that var
will contain asd
. That is because last pipeline element sets var
in a sub-shell which has no access to current shell's environment.
From man bash
:
Each command in a pipeline is executed as a separate process (i.e., in a subshell). See COMMAND EXECUTION ENVIRONMENT for a description of a subshell environment. If the lastpipe option is enabled using the shopt builtin (see the description of shopt below), the last element of a pipeline may be run by the shell process.
I don't know what is may be... Here is better description:
lastpipe
If set, and job control is not active, the shell runs the last command of a pipeline not executed in the background in the current shell environment.
So
set +m # To disable job control
shopt -s lastpipe
echo asd | var=$(cat)
echo $var
and now var
contains asd
.
Thanks @chepner.
Earlier I used to write like:
{ while read;do var="$REPLY";done; } < <(command | filter)
in cases when
var=$(command | filter)
is not suitable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With