406 lines
8.3 KiB
YAML
406 lines
8.3 KiB
YAML
name: "IFS"
|
|
cases:
|
|
- name: "Default IFS value"
|
|
stdin: |
|
|
# Default IFS is space, tab, newline
|
|
[[ "$IFS" == $' \t\n' ]] && echo "IFS has default value"
|
|
|
|
- name: "Field splitting with default IFS"
|
|
stdin: |
|
|
var="one two three
|
|
four"
|
|
echo "Fields:" $var
|
|
|
|
- name: "Field splitting with custom single-char IFS"
|
|
stdin: |
|
|
IFS=':'
|
|
var="one:two:three"
|
|
echo $var
|
|
|
|
- name: "Field splitting with multi-char IFS"
|
|
stdin: |
|
|
IFS=':,'
|
|
var="one:two,three:four"
|
|
echo $var
|
|
|
|
- name: "Empty IFS disables field splitting"
|
|
stdin: |
|
|
IFS=''
|
|
var="one two three"
|
|
echo "[$var]"
|
|
# Should print with all whitespace preserved
|
|
|
|
- name: "Empty IFS with expansion"
|
|
stdin: |
|
|
IFS=''
|
|
var="a b c"
|
|
set -- $var
|
|
echo "Count: $#"
|
|
echo "[$1]"
|
|
|
|
- name: "Unset IFS uses default splitting"
|
|
stdin: |
|
|
unset IFS
|
|
var="one two three"
|
|
echo $var
|
|
|
|
- name: "IFS whitespace vs non-whitespace splitting"
|
|
known_failure: true
|
|
stdin: |
|
|
# Non-whitespace IFS chars create empty fields
|
|
IFS=':'
|
|
var=":one::two:"
|
|
set -- $var
|
|
echo "Count: $#"
|
|
echo "Args: $@"
|
|
|
|
- name: "IFS whitespace splitting ignores leading/trailing"
|
|
stdin: |
|
|
# Whitespace IFS chars ignore leading/trailing
|
|
IFS=' '
|
|
var=" one two "
|
|
set -- $var
|
|
echo "Count: $#"
|
|
echo "Args: $@"
|
|
|
|
- name: "Mixed whitespace and non-whitespace IFS"
|
|
stdin: |
|
|
IFS=' :'
|
|
var="one:two three : four"
|
|
set -- $var
|
|
echo "Count: $#"
|
|
for arg in "$@"; do
|
|
echo "[$arg]"
|
|
done
|
|
|
|
- name: "Mixed IFS leading non-whitespace"
|
|
known_failure: true
|
|
stdin: |
|
|
IFS=': '
|
|
var=":one: :two"
|
|
set -- $var
|
|
echo "Count: $#"
|
|
for arg in "$@"; do
|
|
echo "[$arg]"
|
|
done
|
|
|
|
- name: "Mixed IFS trailing non-whitespace"
|
|
stdin: |
|
|
IFS=' :'
|
|
var="one :two: "
|
|
set -- $var
|
|
echo "Count: $#"
|
|
for arg in "$@"; do
|
|
echo "[$arg]"
|
|
done
|
|
|
|
- name: "IFS only whitespace multiple chars"
|
|
stdin: |
|
|
IFS=$' \t'
|
|
var=" one two three "
|
|
set -- $var
|
|
echo "Count: $#"
|
|
echo "Args: $@"
|
|
|
|
- name: "IFS only non-whitespace multiple chars"
|
|
known_failure: true
|
|
stdin: |
|
|
IFS=':,'
|
|
var=":,one,:,two,:"
|
|
set -- $var
|
|
echo "Count: $#"
|
|
for arg in "$@"; do
|
|
echo "[$arg]"
|
|
done
|
|
|
|
- name: "IFS only tab character"
|
|
stdin: |
|
|
IFS=$'\t'
|
|
var=" a b "
|
|
set -- $var
|
|
echo "Count: $#"
|
|
echo "Args: $@"
|
|
|
|
- name: "IFS only newline character"
|
|
stdin: |
|
|
IFS=$'\n'
|
|
var="
|
|
|
|
a
|
|
|
|
b
|
|
|
|
"
|
|
set -- $var
|
|
echo "Count: $#"
|
|
echo "Args: $@"
|
|
|
|
- name: "IFS affects command substitution"
|
|
stdin: |
|
|
IFS=':'
|
|
result=$(echo "a:b:c")
|
|
# Command substitution itself doesn't split, but expansion does
|
|
set -- $result
|
|
echo "$#"
|
|
echo "$@"
|
|
|
|
- name: "IFS with command substitution multiline"
|
|
stdin: |
|
|
IFS=$'\n'
|
|
result=$(printf "a\nb\nc")
|
|
set -- $result
|
|
echo "Count: $#"
|
|
echo "$1|$2|$3"
|
|
|
|
- name: "IFS affects arithmetic expansion"
|
|
stdin: |
|
|
IFS=' '
|
|
# Arithmetic expansion result is splittable
|
|
set -- $((1 + 1)) $((2 + 2))
|
|
echo "Count: $#"
|
|
echo "$@"
|
|
|
|
- name: "IFS in array expansion"
|
|
stdin: |
|
|
arr=(one two three)
|
|
IFS=':'
|
|
echo "${arr[*]}"
|
|
# With $* should join with first char of IFS
|
|
|
|
- name: "IFS with $* vs $@"
|
|
stdin: |
|
|
set -- one two three
|
|
IFS=':'
|
|
echo "$*"
|
|
echo "$@"
|
|
|
|
- name: "IFS with $* unquoted"
|
|
stdin: |
|
|
set -- "a:b" "c:d"
|
|
IFS=':'
|
|
# Unquoted $* joins then splits
|
|
set -- $*
|
|
echo "Count: $#"
|
|
for arg in "$@"; do
|
|
echo "[$arg]"
|
|
done
|
|
|
|
- name: "IFS null char handling"
|
|
stdin: |
|
|
IFS=':'
|
|
var=""
|
|
set -- $var
|
|
echo "Empty var count: $#"
|
|
|
|
- name: "IFS preservation across commands"
|
|
stdin: |
|
|
IFS=':'
|
|
echo "First: $IFS"
|
|
var="a:b"
|
|
echo $var
|
|
echo "After: $IFS"
|
|
|
|
- name: "IFS in subshell"
|
|
stdin: |
|
|
IFS=':'
|
|
(
|
|
echo "In subshell: [$IFS]"
|
|
var="a:b:c"
|
|
set -- $var
|
|
echo "Count: $#"
|
|
)
|
|
echo "Parent: [$IFS]"
|
|
|
|
- name: "IFS local to command"
|
|
stdin: |
|
|
var="a:b:c"
|
|
IFS=':' echo $var
|
|
# IFS assignment should only affect that command
|
|
echo "After: [$IFS]"
|
|
|
|
- name: "IFS does not affect for loop literal words"
|
|
# nash: fixed by ExpansionPiece::LiteralText (literal words are not field-split)
|
|
stdin: |
|
|
IFS=':'
|
|
for word in a:b:c; do
|
|
echo "[$word]"
|
|
done
|
|
|
|
- name: "IFS affects for loop variable expansion"
|
|
stdin: |
|
|
IFS=':'
|
|
var="a:b:c"
|
|
for word in $var; do
|
|
echo "[$word]"
|
|
done
|
|
|
|
- name: "IFS affects for loop command substitution"
|
|
stdin: |
|
|
IFS=':'
|
|
for word in $(echo "x:y:z"); do
|
|
echo "[$word]"
|
|
done
|
|
|
|
- name: "IFS with quoted vs unquoted expansion"
|
|
stdin: |
|
|
IFS=':'
|
|
var="a:b:c"
|
|
echo "Unquoted:" $var
|
|
echo "Quoted: $var"
|
|
|
|
- name: "IFS with partially quoted expansion"
|
|
# nash: fixed by ExpansionPiece::LiteralText (literal words are not field-split)
|
|
stdin: |
|
|
IFS=':'
|
|
var="a:b:c"
|
|
set -- "$var":more
|
|
echo "Count: $#"
|
|
echo "$@"
|
|
|
|
- name: "IFS whitespace sequence handling"
|
|
stdin: |
|
|
IFS=' '
|
|
var="a b"
|
|
set -- $var
|
|
echo "Count: $#"
|
|
echo "Args: $@"
|
|
|
|
- name: "IFS non-whitespace sequence handling"
|
|
known_failure: true
|
|
stdin: |
|
|
IFS=':'
|
|
var="a::::b"
|
|
set -- $var
|
|
echo "Count: $#"
|
|
for arg in "$@"; do
|
|
echo "[$arg]"
|
|
done
|
|
|
|
- name: "IFS with parameter expansion"
|
|
stdin: |
|
|
IFS=':'
|
|
var="a:b:c"
|
|
result=${var}
|
|
set -- $result
|
|
echo "$#"
|
|
echo "$@"
|
|
|
|
- name: "IFS with parameter expansion default value"
|
|
stdin: |
|
|
IFS=':'
|
|
set -- ${unset:-a:b:c}
|
|
echo "Count: $#"
|
|
echo "$@"
|
|
|
|
- name: "IFS with parameter expansion empty default"
|
|
stdin: |
|
|
IFS=':'
|
|
set -- ${unset:-}
|
|
echo "Count: $#"
|
|
|
|
- name: "IFS with parameter length"
|
|
stdin: |
|
|
IFS=':'
|
|
var="a:b:c"
|
|
# Length expansion returns a number, not subject to further splitting
|
|
len=${#var}
|
|
set -- $len
|
|
echo "Count: $#"
|
|
echo "[$1]"
|
|
|
|
- name: "IFS with glob pattern literal"
|
|
# nash: fixed by ExpansionPiece::LiteralText (literal words are not field-split)
|
|
stdin: |
|
|
IFS=':'
|
|
# Glob patterns as literals shouldn't split
|
|
for word in *.txt:*.sh; do
|
|
echo "[$word]"
|
|
done
|
|
|
|
- name: "IFS newline handling"
|
|
stdin: |
|
|
IFS=$'\n'
|
|
var="a
|
|
b
|
|
c"
|
|
set -- $var
|
|
echo "Count: $#"
|
|
echo "$1|$2|$3"
|
|
|
|
- name: "IFS tab handling"
|
|
stdin: |
|
|
IFS=$'\t'
|
|
var="a b c"
|
|
set -- $var
|
|
echo "Count: $#"
|
|
echo "$1|$2|$3"
|
|
|
|
- name: "IFS with backslash in value"
|
|
stdin: |
|
|
IFS=':'
|
|
var='a\:b:c\:d'
|
|
set -- $var
|
|
echo "Count: $#"
|
|
for arg in "$@"; do
|
|
echo "[$arg]"
|
|
done
|
|
|
|
- name: "IFS first char for joining"
|
|
stdin: |
|
|
set -- a b c
|
|
IFS=':'
|
|
# First char of IFS used for $* joining
|
|
result="$*"
|
|
echo "[$result]"
|
|
|
|
- name: "IFS first char empty IFS"
|
|
known_failure: true
|
|
stdin: |
|
|
set -- a b c
|
|
IFS=''
|
|
result="$*"
|
|
echo "[$result]"
|
|
|
|
- name: "IFS multiple whitespace at start"
|
|
stdin: |
|
|
IFS=' '
|
|
var=" a b"
|
|
set -- $var
|
|
echo "Count: $#"
|
|
echo "$@"
|
|
|
|
- name: "IFS multiple whitespace at end"
|
|
stdin: |
|
|
IFS=' '
|
|
var="a b "
|
|
set -- $var
|
|
echo "Count: $#"
|
|
echo "$@"
|
|
|
|
- name: "IFS with read builtin integration"
|
|
stdin: |
|
|
IFS=':'
|
|
echo "a:b:c" | (read x y z; echo "x=[$x] y=[$y] z=[$z]")
|
|
|
|
- name: "IFS whitespace before non-whitespace"
|
|
known_failure: true
|
|
stdin: |
|
|
IFS=' :'
|
|
var=" :a"
|
|
set -- $var
|
|
echo "Count: $#"
|
|
for arg in "$@"; do
|
|
echo "[$arg]"
|
|
done
|
|
|
|
- name: "IFS non-whitespace before whitespace"
|
|
known_failure: true
|
|
stdin: |
|
|
IFS=': '
|
|
var=": a"
|
|
set -- $var
|
|
echo "Count: $#"
|
|
for arg in "$@"; do
|
|
echo "[$arg]"
|
|
done
|