From 613cec8ea1a9a59a84687057169c617122a7ada2 Mon Sep 17 00:00:00 2001 From: Benjamin Lupton Date: Fri, 25 Oct 2024 11:18:47 +0800 Subject: [PATCH] improvements to TTY and STDIN reporting - add `debug-terminal-(stdin|tty)` - simplify `get-terminal-*-support` checks - `IFS=''` to `IFS=` as they are equivalent - get-terminal-theme: add `--ignore-cache` option - echo-file: correctly handle bat theme in cases where theme could not be detected, such as inside `ssh -T` --- commands.beta/echo-revolving-screen | 2 +- commands.deprecated/is-match | 2 - commands/debug-terminal-stdin | 112 +++++++++++++ commands/debug-terminal-tty | 192 +++++++++++++++++++++ commands/dorothy | 9 +- commands/echo-file | 7 +- commands/echo-revolving-door | 2 +- commands/get-terminal-alternative-support | 8 +- commands/get-terminal-position-support | 13 +- commands/get-terminal-stdin-tty-support | 8 +- commands/get-terminal-theme | 30 ++-- commands/get-terminal-title-support | 8 +- commands/get-terminal-tty-support | 194 +--------------------- commands/read-key | 6 +- sources/stdinargs.bash | 4 +- 15 files changed, 374 insertions(+), 223 deletions(-) create mode 100755 commands/debug-terminal-stdin create mode 100755 commands/debug-terminal-tty diff --git a/commands.beta/echo-revolving-screen b/commands.beta/echo-revolving-screen index 3c9eba3fc..ceaa0d9d1 100755 --- a/commands.beta/echo-revolving-screen +++ b/commands.beta/echo-revolving-screen @@ -64,7 +64,7 @@ function echo_revolving_screen() ( clear_screen=$'\e[H\e[J' local input total_lines=0 status wrapped lines=0 - while IFS='' read -r input || test -n "$input"; do + while IFS= read -r input || test -n "$input"; do eval_capture --statusvar=status --outputvar=wrapped \ -- gfold --width="$option_columns" <<<"$input" #-- echo-wrap --width="$option_columns" -- "$input" diff --git a/commands.deprecated/is-match b/commands.deprecated/is-match index 3e0597a2d..faf8da3ba 100755 --- a/commands.deprecated/is-match +++ b/commands.deprecated/is-match @@ -1,7 +1,5 @@ #!/usr/bin/env bash -# deprecated, use [echo-regexp -q --regexp= -- ] instead - function is_match_test() ( source "$DOROTHY/sources/bash.bash" echo-style --h1="TEST: $0" diff --git a/commands/debug-terminal-stdin b/commands/debug-terminal-stdin new file mode 100755 index 000000000..7a42cc073 --- /dev/null +++ b/commands/debug-terminal-stdin @@ -0,0 +1,112 @@ +#!/usr/bin/env bash +# trunk-ignore-all(shellcheck/SC2319) + +function debug_terminal_stdin() ( + source "$DOROTHY/sources/bash.bash" + + # dependencies + setup-util-file --quiet + + # ===================================== + + local file + file="$(fs-temp --directory='debug-tty-stdin' --file --extension='txt')" + + function r { + local details="$1" status result + __print_lines "$details" + __print_lines '' "$details" >>"$file" + file /dev/stdin >>"$file" || : + file /proc/self/fd/0 >>"$file" || : + file /dev/fd/0 >>"$file" || : + + status=0 + read -t 0 || status=$? + __print_lines "read -t 0: $status" >>"$file" + + status=0 + [[ -t 0 ]] || status=$? + __print_lines "[[ -t 0 ]]: $status" >>"$file" + + status=0 + [[ -p /dev/stdin ]] || status=$? + __print_lines "[[ -p /dev/stdin ]]: $status" >>"$file" + + status=0 + [[ -c /dev/stdin ]] || status=$? + __print_lines "[[ -c /dev/stdin ]]: $status" >>"$file" + + status=0 + [[ -r /dev/stdin ]] || status=$? + __print_lines "[[ -r /dev/stdin ]]: $status" >>"$file" + + status=0 + [[ -w /dev/stdin ]] || status=$? + __print_lines "[[ -w /dev/stdin ]]: $status" >>"$file" + + result='' + status=0 + read -t 5 -rei def result || status=$? + __print_lines "read -rei: $status: $result" >>"$file" + + } + function s { + __print_lines 'custom' + #__print_line + #: + } + function b { + r "BACKGROUND TASK: $1" & + wait $! + } + + # STANDARD + + __print_line + r 'DIRECT' + + __print_line + { s; } | r 'PIPE' + __print_line + { + sleep 1 + s + } | r 'DELAYED PIPE' + + __print_line + r 'REDIRECTION' < <(s) + __print_line + r 'DELAYED REDIRECTION' < <( + sleep 1 + s + ) + + # BACKGROUND + + __print_line + b 'DIRECT' + + __print_line + { s; } | b 'PIPE' + __print_line + { + sleep 1 + s + } | b 'DELAYED PIPE' || : + + __print_line + b 'REDIRECTION' < <(s) + __print_line + b 'DELAYED REDIRECTION' < <( + sleep 1 + s + ) + + __print_lines '' 'DONE' + echo-file -- "$file" +) + +# fire if invoked standalone +if test "$0" = "${BASH_SOURCE[0]}"; then + debug_terminal_stdin "$@" +fi diff --git a/commands/debug-terminal-tty b/commands/debug-terminal-tty new file mode 100755 index 000000000..a28f1c3ac --- /dev/null +++ b/commands/debug-terminal-tty @@ -0,0 +1,192 @@ +#!/usr/bin/env bash + +function debug_terminal_tty() ( + source "$DOROTHY/sources/bash.bash" + + # ===================================== + + function __act { + # $- + __print_lines "\$- = $-" + + # tty: + # alpine doesn't support the [-p] argument + if ! is-apk && __command_exists -- ps; then + __print_lines '' 'tty:' + ps -p "$$" -o tty= || : + fi + + # lsof: + if __command_exists -- lsof; then + __print_lines '' 'lsof:' + lsof -p $$ || : + fi + + # /dev/fd/* + __print_lines '' '/dev/fd/*:' + ls -l /dev/fd/* || : + file /dev/fd/* || : + + # /dev/pts/* + if test -e /dev/pts; then + __print_lines '' '/dev/pts/*:' + ls -l /dev/pts/* || : + file /dev/pts/* || : + fi + + # realpath /dev/fd/* + __print_lines '' 'realpath /dev/fd/*:' + fs-realpath -- /dev/fd/* || : + + # proc: + # https://stackoverflow.com/a/54668834/130638 + if ls /proc/$$/fdinfo/* >/dev/null 2>&1 || grep -q 'flags: 00$' /proc/$$/fdinfo/0; then + __print_lines '' proc_pass + else + __print_lines '' proc_fail + fi + + # attempts at detection + + # -c /dev/stdin to handle background in ssh -T + # note that if everything is captured, such as eval_capture with stdin modification, then this appears true + ( ([[ -n ${SSH_CONNECTION-} && -n ${SSH_CLIENT-} && -z ${SSH_TTY-} ]] && __print_lines is_actually_ssh_T) || __print_lines is_not_actually_ssh_T) || : + ( ([[ (-p /dev/stdin || -c /dev/stdin) && -p /dev/stdout && -p /dev/stderr ]] && ! (: >/dev/stdin) && __print_lines is_ssh_T_or_all_custom) || __print_lines is_neither_ssh_T_or_all_custom) || : + ( (! [[ -c /dev/stdin ]] && (: >/dev/stdin) && __print_lines is_CI) || __print_lines is_not_CI) || : + + ( (tty -s && __print_lines tty_s_pass) || __print_lines tty_s_fail) || : + + ( (test -t 0 && __print_lines test_t_stdin_pass) || __print_lines test_t_stdin_fail) || : + ( (test -t 1 && __print_lines test_t_stdout_pass) || __print_lines test_t_stdout_fail) || : + ( (test -t 2 && __print_lines test_t_stderr_pass) || __print_lines test_t_stderr_fail) || : + + ( (test -p /dev/stdin && __print_lines test_p_stdin_pass) || __print_lines test_p_stdin_fail) || : + ( (test -p /dev/stdout && __print_lines test_p_stdout_pass) || __print_lines test_p_stdout_fail) || : + ( (test -p /dev/stderr && __print_lines test_p_stderr_pass) || __print_lines test_p_stderr_fail) || : + ( (test -p /dev/tty && __print_lines test_p_tty_pass) || __print_lines test_p_tty_fail) || : + + ( (test -c /dev/stdin && __print_lines test_c_stdin_pass) || __print_lines test_c_stdin_fail) || : + ( (test -c /dev/stdout && __print_lines test_c_stdout_pass) || __print_lines test_c_stdout_fail) || : + ( (test -c /dev/stderr && __print_lines test_c_stderr_pass) || __print_lines test_c_stderr_fail) || : + ( (test -c /dev/tty && __print_lines test_c_tty_pass) || __print_lines test_c_tty_fail) || : + + # check if reading is even possible (If TIMEOUT is 0, read returns immediately, without trying to read any data, returning success only if input is available on the specified file descriptor.) + ( (read -t 0 && __print_lines read_default_pass) || __print_lines read_default_fail) || : + ( (read -t 0 /dev/stdin && __print_lines noop_to_stdin_pass) || __print_lines noop_to_stdin_fail) || : + ( (: >/dev/stdout && __print_lines noop_to_stdout_pass) || __print_lines noop_to_stdout_fail) || : + ( (: >/dev/stderr && __print_lines noop_to_stderr_pass) || __print_lines noop_to_stderr_fail) || : + ( (: >/dev/tty && __print_lines noop_to_tty_pass) || __print_lines noop_to_tty_fail) || : + + ( (: /dev/stdin && __print_lines noop_bidirectonal_stdin_pass) || __print_lines noop_bidirectonal_stdin_fail) || : + ( (: /dev/stdout && __print_lines noop_bidirectonal_stdout_pass) || __print_lines noop_bidirectonal_stdout_fail) || : + ( (: /dev/stderr && __print_lines noop_bidirectonal_stderr_pass) || __print_lines noop_bidirectonal_stderr_fail) || : + ( (: /dev/tty && __print_lines noop_bidirectonal_tty_pass) || __print_lines noop_bidirectonal_tty_fail) || : + } + + local stdout stderr + + __act + + __print_lines '' '' '### testing pipe ###' + __print_lines 'testing pipe' | __act + + __print_lines '' '' '### testing delayed pipe ###' + { + sleep 3 + __print_line + } | __act || : # this is necessary, as otherwise the pipe fails with 141 + + __print_lines '' '' '### testing <<< ###' + __act <<<'testing <<<' + + __print_lines '' '' '### testing < <(...) ###' + __act < <(__print_lines 'testing <<<') + + __print_lines '' '' '### testing background ###' + __act & + wait $! + + __print_lines '' '' '### --stdoutvar ###' + stdout='' + stderr='' + eval_capture --stdoutvar=stdout -- __act + __print_lines 'stdout =' + echo-lines --indent=' ' --stdin <<<"$stdout" + __print_lines 'stderr =' + echo-lines --indent=' ' --stdin <<<"$stderr" + + __print_lines '' '' '### --stderrvar ###' + stdout='' + stderr='' + eval_capture --stderrvar=stderr -- __act + __print_lines 'stdout =' + echo-lines --indent=' ' --stdin <<<"$stdout" + __print_lines 'stderr =' + echo-lines --indent=' ' --stdin <<<"$stderr" + + __print_lines '' '' '### --stdoutvar --stderrvar ###' + stdout='' + stderr='' + eval_capture --stdoutvar=stdout --stderrvar=stderr -- __act + __print_lines 'stdout =' + echo-lines --indent=' ' --stdin <<<"$stdout" + __print_lines 'stderr =' + echo-lines --indent=' ' --stdin <<<"$stderr" + + __print_lines '' '' '### pipe to --stdoutvar --stderrvar ###' + stdout='' + stderr='' + __print_lines 'testing pipe' | eval_capture --stdoutvar=stdout --stderrvar=stderr -- __act + __print_lines 'stdout =' + echo-lines --indent=' ' --stdin <<<"$stdout" + __print_lines 'stderr =' + echo-lines --indent=' ' --stdin <<<"$stderr" + + __print_lines '' '' '### delayed pipe to --stdoutvar --stderrvar ###' + stdout='' + stderr='' + { + sleep 3 + __print_line + } | eval_capture --stdoutvar=stdout --stderrvar=stderr -- __act || : + __print_lines 'stdout =' + echo-lines --indent=' ' --stdin <<<"$stdout" + __print_lines 'stderr =' + echo-lines --indent=' ' --stdin <<<"$stderr" + + __print_lines '' '' '### <<< to --stdoutvar --stderrvar ###' + stdout='' + stderr='' + eval_capture --stdoutvar=stdout --stderrvar=stderr -- __act <<<'testing <<<' + __print_lines 'stdout =' + echo-lines --indent=' ' --stdin <<<"$stdout" + __print_lines 'stderr =' + echo-lines --indent=' ' --stdin <<<"$stderr" + + __print_lines '' '' '### < <(...) to --stdoutvar --stderrvar ###' + stdout='' + stderr='' + eval_capture --stdoutvar=stdout --stderrvar=stderr -- __act < <(__print_lines 'testing <<<') + __print_lines 'stdout =' + echo-lines --indent=' ' --stdin <<<"$stdout" + __print_lines 'stderr =' + echo-lines --indent=' ' --stdin <<<"$stderr" +) + +# fire if invoked standalone +if test "$0" = "${BASH_SOURCE[0]}"; then + debug_terminal_tty "$@" +fi diff --git a/commands/dorothy b/commands/dorothy index ac4ccfce9..426c8b4f0 100755 --- a/commands/dorothy +++ b/commands/dorothy @@ -1905,6 +1905,13 @@ function dorothy_() ( echo-style --h1='Dorothy Tests' source "$DOROTHY/sources/ripgrep.bash" + # run relevant debugs + __print_lines '' 'debug-terminal-stdin:' + debug-terminal-stdin || : + __print_lines '' 'debug-terminal-tty:' + debug-terminal-tty || : + __print_lines '' + # able to test on bash v3? local bash has_macos_bash_v3='no' bash="$(type -P bash)" @@ -1916,7 +1923,7 @@ function dorothy_() ( local commands filepath filename failures=() scan_paths=( "$DOROTHY/commands/" "$DOROTHY/commands.beta/" - "$DOROTHY/commands.deprecated/" + # "$DOROTHY/commands.deprecated/" <-- don't run deprecated tests, as that will cause deprecated warnings, which cases dorothy-warnings test to fail ) if test -d "$DOROTHY/user"; then if test -d "$DOROTHY/user/commands"; then diff --git a/commands/echo-file b/commands/echo-file index fea3168ba..8e1301a29 100755 --- a/commands/echo-file +++ b/commands/echo-file @@ -112,7 +112,7 @@ function echo_file() ( ) fi if test -z "${BAT_THEME-}"; then - terminal_theme="$(get-terminal-theme || :)" + terminal_theme="$(get-terminal-theme --ignore-cache || :)" if test "$terminal_theme" = 'light'; then bat_cmd+=( --theme=ansi @@ -121,10 +121,7 @@ function echo_file() ( bat_cmd+=( --theme=1337 ) - else - bat_cmd=() - # bat is installed, but without knowing the terminal theme, we cannot be sure that the bat theme is readable - fi + fi # else bat is installed, but without knowing the terminal theme, we cannot be sure that the bat theme is readable fi function echo_file_bat { diff --git a/commands/echo-revolving-door b/commands/echo-revolving-door index 347a87176..09d8df1ca 100755 --- a/commands/echo-revolving-door +++ b/commands/echo-revolving-door @@ -55,7 +55,7 @@ function echo_revolving_door() ( else local input negative_columns negative_columns="$((option_columns * -1))" - while IFS='' read -r input || test -n "$input"; do + while IFS= read -r input || test -n "$input"; do if test -z "$input"; then continue fi diff --git a/commands/get-terminal-alternative-support b/commands/get-terminal-alternative-support index 82853a99d..2656ced44 100755 --- a/commands/get-terminal-alternative-support +++ b/commands/get-terminal-alternative-support @@ -45,11 +45,15 @@ function get_terminal_alternative_support() ( # ===================================== # Action + function __check { + is-ci + } + if test "$option_quiet" = 'yes'; then - if is-ci; then + if __check; then return 1 fi - elif is-ci; then + elif __check; then __print_lines 'no' else __print_lines 'yes' diff --git a/commands/get-terminal-position-support b/commands/get-terminal-position-support index 4a6dd9eaa..2c4dc1382 100755 --- a/commands/get-terminal-position-support +++ b/commands/get-terminal-position-support @@ -55,14 +55,19 @@ function get_terminal_position_support() ( # use a 2 second timeout, as otherwise on macos sonoma will wait forever # shorter timeouts aren't suitable as slower machines take a while for the response # the read will complete immediately upon a response thanks to [-d R] which completes reading when the R is read, which is the final character of the response - local _ line column - IFS='[;' read -t 2 -srd R -p $'\e[6n' _ line column 2>/dev/null <"$option_device_file" || : + function __check { + local _ line column + IFS='[;' read -t 2 -srd R -p $'\e[6n' _ line column 2>/dev/null <"$option_device_file" || : + test -n "${line-}" -a -n "${column-}" + return + } + if test "$option_quiet" = 'yes'; then - if test -n "${line-}" -a -n "${column-}"; then + if __check; then return 0 fi return 1 - elif test -n "${line-}" -a -n "${column-}"; then + elif __check; then __print_lines 'yes' else __print_lines 'no' diff --git a/commands/get-terminal-stdin-tty-support b/commands/get-terminal-stdin-tty-support index cd3e746a5..c232f77b7 100755 --- a/commands/get-terminal-stdin-tty-support +++ b/commands/get-terminal-stdin-tty-support @@ -45,10 +45,14 @@ function get_terminal_stdin_tty_support() ( # ===================================== # Action + function __check { + [[ -t 0 ]] + } + if test "$option_quiet" = 'yes'; then - test -t 0 + __check return - elif test -t 0; then + elif __check; then __print_lines 'yes' else __print_lines 'no' diff --git a/commands/get-terminal-theme b/commands/get-terminal-theme index 69e07ca64..6e259caba 100755 --- a/commands/get-terminal-theme +++ b/commands/get-terminal-theme @@ -19,6 +19,9 @@ function get_terminal_theme() ( --refresh-cache Clear the cache, and fetch the terminal theme. + --ignore-cache + Don't read nor write to the cache. + --clear-cache Only clear the cache, do not fetch the terminal theme. @@ -33,7 +36,7 @@ function get_terminal_theme() ( } # process - local item option_fallback='dark' option_clear_cache='no' option_refresh_cache='no' + local item option_fallback='dark' option_clear_cache='no' option_refresh_cache='no' option_ignore_cache='no' while test "$#" -ne 0; do item="$1" shift @@ -41,6 +44,7 @@ function get_terminal_theme() ( '--help' | '-h') help ;; '--refresh-cache') option_refresh_cache='yes' ;; '--clear-cache') option_clear_cache='yes' ;; + '--ignore-cache') option_ignore_cache='yes' ;; '--fallback='*) option_fallback="${item#*=}" ;; '--no-fallback') option_fallback='' ;; '--'*) help "An unrecognised flag was provided: $item" ;; @@ -57,19 +61,21 @@ function get_terminal_theme() ( # prepare cache local cache_file - cache_file="$(fs-temp --file='terminal-theme')" # if clearing cache, only clear cache - if test "$option_clear_cache" = 'yes' -o "$option_refresh_cache" = 'yes'; then - if test -f "$cache_file"; then - rm "$cache_file" - fi - if test "$option_clear_cache" = 'yes'; then + if test "$option_ignore_cache" != 'yes'; then + cache_file="$(fs-temp --file='terminal-theme')" + if test "$option_clear_cache" = 'yes' -o "$option_refresh_cache" = 'yes'; then + if test -f "$cache_file"; then + rm "$cache_file" + fi + if test "$option_clear_cache" = 'yes'; then + return 0 + fi + elif test -f "$cache_file"; then + cat "$cache_file" return 0 fi - elif test -f "$cache_file"; then - cat "$cache_file" - return 0 fi # on macos, one can do this: @@ -168,7 +174,9 @@ function get_terminal_theme() ( for method in "${methods[@]}"; do "$method" if test -n "$theme"; then - tee "$cache_file" <<<"$theme" + if test "$option_ignore_cache" != 'yes'; then + tee "$cache_file" <<<"$theme" + fi return 0 fi done diff --git a/commands/get-terminal-title-support b/commands/get-terminal-title-support index 921914d7e..241313024 100755 --- a/commands/get-terminal-title-support +++ b/commands/get-terminal-title-support @@ -45,11 +45,15 @@ function get_terminal_title_support() ( # ===================================== # Action + function __check { + is-ci || is-vscode + } + if test "$option_quiet" = 'yes'; then - if is-ci || is-vscode; then + if __check; then return 1 fi - elif is-ci || is-vscode; then + elif __check; then __print_lines 'no' else __print_lines 'yes' diff --git a/commands/get-terminal-tty-support b/commands/get-terminal-tty-support index daad42093..8162afa7f 100755 --- a/commands/get-terminal-tty-support +++ b/commands/get-terminal-tty-support @@ -1,185 +1,5 @@ #!/usr/bin/env bash -function get_terminal_tty_support_test() ( - source "$DOROTHY/sources/bash.bash" - source "$(type -P eval-tester)" - echo-style --h1="TEST: $0" - - function __do_test { - __print_lines "\$- = $-" - - # alpine doesn't support the [-p] argument - if ! is-apk && __command_exists -- ps; then - __print_lines '' 'tty:' - ps -p "$$" -o tty= || : - fi - - if __command_exists -- lsof; then - __print_lines '' 'lsof:' - lsof -p $$ || : - fi - - __print_lines '' '/dev/fd/*:' - ls -l /dev/fd/* || : - file /dev/fd/* || : - - if test -e /dev/pts; then - __print_lines '' '/dev/pts/*:' - ls -l /dev/pts/* || : - file /dev/pts/* || : - fi - - __print_lines '' 'realpath /dev/fd/*:' - fs-realpath -- /dev/fd/* || : - - # https://stackoverflow.com/a/54668834/130638 - if ls /proc/$$/fdinfo/* >/dev/null 2>&1 || grep -q 'flags: 00$' /proc/$$/fdinfo/0; then - __print_lines '' proc_pass - else - __print_lines '' proc_fail - fi - - # attempts at detection - - # -c /dev/stdin to handle background in ssh -T - # note that if everything is captured, such as eval_capture with stdin modification, then this appears true - ( ([[ (-p /dev/stdin || -c /dev/stdin) && -p /dev/stdout && -p /dev/stderr ]] && ! (: >/dev/stdin) && __print_lines is_ssh_T_or_all_custom) || __print_lines is_neither_ssh_T_or_all_custom) || : - ( (! [[ -c /dev/stdin ]] && (: >/dev/stdin) && __print_lines is_CI) || __print_lines is_not_CI) || : - - ( (tty -s && __print_lines tty_s_pass) || __print_lines tty_s_fail) || : - - ( (test -t 0 && __print_lines test_t_stdin_pass) || __print_lines test_t_stdin_fail) || : - ( (test -t 1 && __print_lines test_t_stdout_pass) || __print_lines test_t_stdout_fail) || : - ( (test -t 2 && __print_lines test_t_stderr_pass) || __print_lines test_t_stderr_fail) || : - - ( (test -p /dev/stdin && __print_lines test_p_stdin_pass) || __print_lines test_p_stdin_fail) || : - ( (test -p /dev/stdout && __print_lines test_p_stdout_pass) || __print_lines test_p_stdout_fail) || : - ( (test -p /dev/stderr && __print_lines test_p_stderr_pass) || __print_lines test_p_stderr_fail) || : - ( (test -p /dev/tty && __print_lines test_p_tty_pass) || __print_lines test_p_tty_fail) || : - - ( (test -c /dev/stdin && __print_lines test_c_stdin_pass) || __print_lines test_c_stdin_fail) || : - ( (test -c /dev/stdout && __print_lines test_c_stdout_pass) || __print_lines test_c_stdout_fail) || : - ( (test -c /dev/stderr && __print_lines test_c_stderr_pass) || __print_lines test_c_stderr_fail) || : - ( (test -c /dev/tty && __print_lines test_c_tty_pass) || __print_lines test_c_tty_fail) || : - - # check if reading is even possible (If TIMEOUT is 0, read returns immediately, without trying to read any data, returning success only if input is available on the specified file descriptor.) - ( (read -t 0 && __print_lines read_default_pass) || __print_lines read_default_fail) || : - ( (read -t 0 /dev/stdin && __print_lines noop_to_stdin_pass) || __print_lines noop_to_stdin_fail) || : - ( (: >/dev/stdout && __print_lines noop_to_stdout_pass) || __print_lines noop_to_stdout_fail) || : - ( (: >/dev/stderr && __print_lines noop_to_stderr_pass) || __print_lines noop_to_stderr_fail) || : - ( (: >/dev/tty && __print_lines noop_to_tty_pass) || __print_lines noop_to_tty_fail) || : - - ( (: /dev/stdin && __print_lines noop_bidirectonal_stdin_pass) || __print_lines noop_bidirectonal_stdin_fail) || : - ( (: /dev/stdout && __print_lines noop_bidirectonal_stdout_pass) || __print_lines noop_bidirectonal_stdout_fail) || : - ( (: /dev/stderr && __print_lines noop_bidirectonal_stderr_pass) || __print_lines noop_bidirectonal_stderr_fail) || : - ( (: /dev/tty && __print_lines noop_bidirectonal_tty_pass) || __print_lines noop_bidirectonal_tty_fail) || : - } - - local stdout stderr - - __do_test - - __print_lines '' '' '### testing pipe ###' - __print_lines 'testing pipe' | __do_test - - __print_lines '' '' '### testing delayed pipe ###' - { - sleep 3 - __print_line - } | __do_test || : # this is necessary, as otherwise the pipe fails with 141 - - __print_lines '' '' '### testing <<< ###' - __do_test <<<'testing <<<' - - __print_lines '' '' '### testing < <(...) ###' - __do_test < <(__print_lines 'testing <<<') - - __print_lines '' '' '### testing background ###' - __do_test & - wait $! - - __print_lines '' '' '### --stdoutvar ###' - stdout='' - stderr='' - eval_capture --stdoutvar=stdout -- __do_test - __print_lines 'stdout =' - echo-lines --indent=' ' --stdin <<<"$stdout" - __print_lines 'stderr =' - echo-lines --indent=' ' --stdin <<<"$stderr" - - __print_lines '' '' '### --stderrvar ###' - stdout='' - stderr='' - eval_capture --stderrvar=stderr -- __do_test - __print_lines 'stdout =' - echo-lines --indent=' ' --stdin <<<"$stdout" - __print_lines 'stderr =' - echo-lines --indent=' ' --stdin <<<"$stderr" - - __print_lines '' '' '### --stdoutvar --stderrvar ###' - stdout='' - stderr='' - eval_capture --stdoutvar=stdout --stderrvar=stderr -- __do_test - __print_lines 'stdout =' - echo-lines --indent=' ' --stdin <<<"$stdout" - __print_lines 'stderr =' - echo-lines --indent=' ' --stdin <<<"$stderr" - - __print_lines '' '' '### pipe to --stdoutvar --stderrvar ###' - stdout='' - stderr='' - __print_lines 'testing pipe' | eval_capture --stdoutvar=stdout --stderrvar=stderr -- __do_test - __print_lines 'stdout =' - echo-lines --indent=' ' --stdin <<<"$stdout" - __print_lines 'stderr =' - echo-lines --indent=' ' --stdin <<<"$stderr" - - __print_lines '' '' '### delayed pipe to --stdoutvar --stderrvar ###' - stdout='' - stderr='' - { - sleep 3 - __print_line - } | eval_capture --stdoutvar=stdout --stderrvar=stderr -- __do_test || : - __print_lines 'stdout =' - echo-lines --indent=' ' --stdin <<<"$stdout" - __print_lines 'stderr =' - echo-lines --indent=' ' --stdin <<<"$stderr" - - __print_lines '' '' '### <<< to --stdoutvar --stderrvar ###' - stdout='' - stderr='' - eval_capture --stdoutvar=stdout --stderrvar=stderr -- __do_test <<<'testing <<<' - __print_lines 'stdout =' - echo-lines --indent=' ' --stdin <<<"$stdout" - __print_lines 'stderr =' - echo-lines --indent=' ' --stdin <<<"$stderr" - - __print_lines '' '' '### < <(...) to --stdoutvar --stderrvar ###' - stdout='' - stderr='' - eval_capture --stdoutvar=stdout --stderrvar=stderr -- __do_test < <(__print_lines 'testing <<<') - __print_lines 'stdout =' - echo-lines --indent=' ' --stdin <<<"$stdout" - __print_lines 'stderr =' - echo-lines --indent=' ' --stdin <<<"$stderr" - - echo-style --g1="TEST: $0" - return 0 -) function get_terminal_tty_support() ( source "$DOROTHY/sources/bash.bash" @@ -225,10 +45,14 @@ function get_terminal_tty_support() ( # ===================================== # Action - if test "$option_quiet" = 'yes'; then + function __check { (: /dev/tty) &>/dev/null + } + + if test "$option_quiet" = 'yes'; then + __check return - elif (: /dev/tty) &>/dev/null; then + elif __check; then __print_lines 'yes' else __print_lines 'no' @@ -237,9 +61,5 @@ function get_terminal_tty_support() ( # fire if invoked standalone if test "$0" = "${BASH_SOURCE[0]}"; then - if test "$*" = '--test'; then - get_terminal_tty_support_test - else - get_terminal_tty_support "$@" - fi + get_terminal_tty_support "$@" fi diff --git a/commands/read-key b/commands/read-key index 7b8509cc1..e5a2f91ce 100755 --- a/commands/read-key +++ b/commands/read-key @@ -232,15 +232,15 @@ function read_key() ( function read_and_flush { # read local status=0 - IFS='' read -rsn1 -t "$option_timeout" input || status=$? + IFS= read -rsn1 -t "$option_timeout" input || status=$? if test "$status" -eq 0; then add "$input" while :; do - # IFS='' allows the space character [ ] to be indentified + # IFS= allows the space character [ ] to be indentified # -r allows backslash key [\] to be kept # -s prevents the input from being echoed # -n1 reads only one character, which is necessary surprisingly to read non-printable characters - if ! IFS='' read -rsn1 -t "$subsequent_timeout" input; then + if ! IFS= read -rsn1 -t "$subsequent_timeout" input; then break fi add "$input" diff --git a/sources/stdinargs.bash b/sources/stdinargs.bash index d1c7d9d7f..e324762e8 100644 --- a/sources/stdinargs.bash +++ b/sources/stdinargs.bash @@ -142,9 +142,9 @@ function stdinargs { # for each line, call `on_line` or `on_input` # for each inline, call `on_inline` or `on_line` or `on_input` # [read -t 0 line] will not read anything, so it must be done seperately - # IFS='' to not trim whitespace lines (e.g. ' ' would otherwise become '') + # IFS= to not trim whitespace lines (e.g. ' ' would otherwise become '') # trunk-ignore(shellcheck/SC2162) - while ([[ $timeout_immediate == 'no' ]] || read -t 0) && IFS='' read "${read_args[@]}" line; do + while ([[ $timeout_immediate == 'no' ]] || read -t 0) && IFS= read "${read_args[@]}" line; do had_line='yes' if [[ $complete == 'yes' ]]; then break