How can I send characters to a command as though they came from a file?

For example I tried:

wc < "apple pear orange"
-bash: apple pear orange: No such file or directory
share|improve this question

In shells that support here strings, including bash, zsh and ksh93, you can use

wc <<< "apple pear orange"
share|improve this answer
    
@Kusalananda thanks - I edited your info in – steeldriver yesterday

Two other approaches (which allow multiple-line input with no extra effort):

  1. Use a "here document":

    $ wc << EOF
    apple pear orange
    EOF
      1       3      18
    $

    The EOF string is a delimiter.  You can use any string; EOF is just a conventional choice.

  2. Use the tty as the input:

    $ wc
    apple pear orange
    Ctrl+D
      1       3      18
    $

    This has the drawback that the program starts running, and starts reading the input, as soon as you type its name.  This can be disconcerting; for example:

    $ grep v
    The quick brown fox             (typed)
    jumps over                      (typed)
    jumps over                      (This is output from grep!)
    the lazy dog.                   (typed)
    Ctrl+D
                                    (No output here)
    $
share|improve this answer
    
For the record: The <<< form also allows multiple-line input with no extra effort, since the "-enclosed string can contain newlines. Of course the << EOF form (the original here-doc syntax) is easier to read if you have multi-line input. – alexis 22 hours ago

you can use a pipe

echo "apple pear orange" | wc
share|improve this answer
6  
A pipe ist not the same as "reading from a file". For example you can't seek backwards in a pipe, whereas you can in a file. – rbialon yesterday

Although there are several valid solutions here, another syntax that can be useful sometimes, is to run a command in <(). This would allow you to create more than 1 file-descriptor object on a command line.

This can be useful when you're doing something like comparing long strings of text, or if you want to diff some content that's not in a file.

For example, comparing the hosts files on two nodes without having to copy the hosts file to the localhost:

diff -Naur <(cat /etc/hosts) <(ssh -q otherhost 'cat /etc/hosts')

The < redirects a file to STDIN, and the () create a subshell to run the command between the parenthesis. It's the STDOUT from the subshell that is passed to STDIN of the command being run.

It's an easier way to create more than 1 input "file" to a command than trying to use multiple here docs, or trying to echo multiple commands to a pipeline to the final command.

share|improve this answer
    
<fileorpathname redirects stdin, but <(subcmd) does not; it substitutes a name that when/if opened by the program can read stdout from subcmd. < <(subcmd) (space required) does redirect stdin from that file, almost like subcmd |. Your diff could read one of its inputs from stdin by specifying an argument of - but not both. – dave_thompson_085 2 hours ago

You may want to use something similar to expect. Following is a simple example of opening a remote telnet session, waiting for the prompt, send some data, wait for a response, sleep and exit.

#!/usr/bin/expect
spawn telnet localhost 8555
expect "Escape character is '^]'."
send "Hello World\n"
expect "Connection closed by foreign host."
sleep 1
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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