# Iteration 15: Process Substitution
# === Basic process substitution ===
=== simple input process substitution
cat <(echo hello)
---
(command (word "cat") (word "<(echo hello)"))
---
=== simple output process substitution
echo hello > >(cat)
---
(command (word "echo") (word "hello") (redirect ">" ">(cat)"))
---
=== process substitution as argument
diff <(ls dir1) <(ls dir2)
---
(command (word "diff") (word "<(ls dir1)") (word "<(ls dir2)"))
---
=== pipeline inside process substitution
cat <(ls | sort)
---
(command (word "cat") (word "<(ls | sort)"))
---
=== pipeline inside output process substitution
echo test > >(grep x | tee out.txt)
---
(command (word "echo") (word "test") (redirect ">" ">(grep x | tee out.txt)"))
---
=== list inside process substitution
cat <(echo a; echo b)
---
(command (word "cat") (word "<(echo a; echo b)"))
---
=== and list inside process substitution
cat <(true && echo yes)
---
(command (word "cat") (word "<(true && echo yes)"))
---
=== two input process substitutions
paste <(seq 5) <(seq 5 10)
---
(command (word "paste") (word "<(seq 5)") (word "<(seq 5 10)"))
---
=== mixed input and output process substitutions
tee >(cat > a.txt) >(cat > b.txt) < <(echo input)
---
(command (word "tee") (word ">(cat > a.txt)") (word ">(cat > b.txt)") (redirect "<" "<(echo input)"))
---
=== process substitution as redirect target
cat < <(echo hello)
---
(command (word "cat") (redirect "<" "<(echo hello)"))
---
=== process substitution with fd
exec 3< <(echo data)
---
(command (word "exec") (redirect "<" "<(echo data)"))
---
=== command substitution inside process substitution
cat <(echo $(whoami))
---
(command (word "cat") (word "<(echo $(whoami))"))
---
=== process substitution inside command substitution
echo $(cat <(echo nested))
---
(command (word "echo") (word "$(cat <(echo nested))"))
---
=== process substitution with subshell
cat <((echo hello))
---
(command (word "cat") (word "<((echo hello))"))
---
=== process substitution in pipeline
cat <(echo hello) | grep h
---
(pipe (command (word "cat") (word "<(echo hello)")) (command (word "grep") (word "h")))
---
=== process substitution in list
cat <(echo a) && echo done
---
(and (command (word "cat") (word "<(echo a)")) (command (word "echo") (word "done")))
---
=== process substitution in while body
while true; do cat <(echo hello); done
---
(while (command (word "true")) (command (word "cat") (word "<(echo hello)")))
---
=== process substitution with no space before
cat<(echo hello)
---
(command (word "cat<(echo hello)"))
---
=== process substitution with variables
cat <(echo $HOME)
---
(command (word "cat") (word "<(echo $HOME)"))
---
=== empty process substitution
cat <(:)
---
(command (word "cat") (word "<(:)"))
---
=== process substitution with arithmetic
cat <(echo $((1+2)))
---
(command (word "cat") (word "<(echo $((1+2)))"))
---
=== process substitution with quoted content
cat <(echo "hello world")
---
(command (word "cat") (word "<(echo \"hello world\")"))
---
=== process substitution with single quotes
cat <(echo 'no $expansion')
---
(command (word "cat") (word "<(echo 'no $expansion')"))
---
=== nested process substitutions
cat <(cat <(echo nested))
---
(command (word "cat") (word "<(cat <(echo nested))"))
---
=== process substitution with brace expansion in command
cat <(echo ${var:-default})
---
(command (word "cat") (word "<(echo ${var:-default})"))
---
=== output process substitution standalone
tee >(cat)
---
(command (word "tee") (word ">(cat)"))
---
=== process substitution with backticks
cat <(echo `whoami`)
---
(command (word "cat") (word "<(echo `whoami`)"))
---
=== multiple output process substitutions
tee >(cat >a) >(cat >b)
---
(command (word "tee") (word ">(cat > a)") (word ">(cat > b)"))
---
=== process substitution in double quotes
echo "<(not expanded)"
---
(command (word "echo") (word "\"<(not expanded)\""))
---
=== process substitution adjacent to text
catfile<(echo x)
---
(command (word "catfile<(echo x)"))
---
=== process substitution with heredoc inside
cat <(cat <<EOF
hello
EOF
)
---
(command (word "cat") (word "<(cat <<EOF\nhello\nEOF\n)"))
---
=== process substitution in redirect with pipeline
read x < <(cmd1|cmd2)
---
(command (word "read") (word "x") (redirect "<" "<(cmd1 | cmd2)"))
---
=== apostrophe in comment inside process substitution
f() {
cat < <(
# it's a comment
echo
)
}
---
(function "f" (brace-group (command (word "cat") (redirect "<" "<(echo)"))))
---