Search code examples
bashshellparametersrealpathifs

command line parameters separated by null character


As filenames may contain spaces and new lines \n, I am using null character as field separator. But I do not know how to say to find that the input directories are null character separated.

My failed attempt:

foo()
{
  IFS='\0'
  find "$@"
}

$ mkdir 'oneword' 'two words'
$ IFS='\0' foo $(realpath -z 'oneword' 'two words')

How to tell find that the input directories are separated by zeros?


Solution

  • One way is to use xargs:

    realpath -z 'oneword' 'two words' | xargs -0 find
    

    Or:

    foo() {
      local A=() I=0 IFS=''
      while read -rd $'\0' A[I++]; do :; done 
      find "${A[@]}"
    }
    realpath -z 'oneword' 'two words' | foo  ## Under subshell or pipe
    foo < <(realpath -z 'oneword' 'two words')  ## No subshell
    

    You can use another fd if needed:

    foo() {
      local A=() I=0 IFS=''
      while read -rd $'\0' -u 4 A[I++]; do :; done 
      find "${A[@]}"
    }
    foo 4< <(realpath -z 'oneword' 'two words')
    

    Note: Using IFS to split your variable's values to multiple arguments can cause pathname expansion and is not commendable. It requires modification of IFS as well which could affect other functions.