6

Is there a way to execute a command with arguments in linux without whitespaces?

cat file.txt

needs to be:

cat(somereplacementforthiswhitespace)file.txt
  • if the file name is " file.txt" then can you can use cat \ file.txt (try \ followed by tab completion) – rob Mar 14 '17 at 9:22
  • This is an example, i want to use more commands then only cat :( btw, I can't use any sort of whitespace, (tab is a whitespace) – Rob Mar 14 '17 at 9:29
  • 4
    Any reason for this? – Kusalananda Mar 14 '17 at 10:37
  • 1
    @Kusalananda Sounds like a hacking exercise where a filter is to be circumvented. – countermode Mar 14 '17 at 10:43
  • 3
    @countermode More like some script that isn't properly quoting a variable. – Kusalananda Mar 14 '17 at 10:45
7

If only there was a variable whose value is a space… Or more generally, contains a space.

cat${IFS}file.txt

The default value of IFS is space, tab, newline. All of these characters are whitespace. If you need a single space, you can use ${IFS%??}.

More precisely, the reason this works has to do with how word splitting works. Critically, it's applied after substituting the value of variables. And word splitting treats each character in the value of IFS as a separator, so by construction, as long as IFS is set to a non-empty value, ${IFS} separates words. If IFS is more than one character long, each character is a word separator. Consecutive separator characters that are whitespace are treated as a single separator, so the result of the expansion of cat${IFS}file.txt is two words: cat and file.txt. Non-whitespace separators are treated separately, with something like IFS=',.'; cat${IFS}file.txt, cat would receive two arguments: an empty argument and file.txt.

  • This is great! How does this work? Why does ${IFS%?} evaluate to a space? – loneboat May 2 at 19:17
  • Awesome, that makes sense. I found documentation on the IFS var, but didn't understand the rest. Thank you for explaining! – loneboat May 2 at 20:16
  • 1
    @loneboat Actually, while my comment was correct, it was a bit misleading. I've edited my answer with a more detailed explanation. – Gilles May 2 at 20:25
5

I found a way assuming a shell that supports csh-like brace expansion like ksh, bash or yash -o brace-expand (zsh supports brace expansion, but not as the first argument like that as that conflicts with command grouping):

{cat,file.txt}

with this way you don't have to use whitespaces in your argument.

1

One alternative is to use the value of IFS with the expansion of a variable:

$ echo Hello! > file.txt

$ IFS=:
$ a=cat:file.txt
$ $a
Hello!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.