38

The difference is caused by a newline added to the here string. See the Bash manual: The result is supplied as a single string, with a newline appended, to the command on its standard input (or file descriptor n if n is specified). wc is counting in the same way, but its input is different.


26

It's a succeeding newline added by the here-string redirector: $ s="hello" $ hexdump -C <<<"$s" 00000000 68 65 6c 6c 6f 0a |hello.| 00000006 $ printf "$s" | hexdump -C 00000000 68 65 6c 6c 6f |hello| 00000005


21

bash -c 'some command' retains access to the standard input of the caller, so read or commands reading from standard input will work normally. bash <<< 'some command' replaces that input with the line being passed in, so bash -c cat and bash <<< cat do different things. $ bash -c cat abc abc ^D $ bash <<< cat $ On the other hand, ...


17

That's because in <<< $line, bash does word splitting, (though not globbing) on $line as it's not quoted there and then joins the resulting words with the space character (and puts that in a temporary file followed by a newline character and makes that the stdin of cut). $ a=a,b,,c bash -c 'IFS=","; sed -n l <<< $a' a b c$ tab happens to ...


13

No, here strings are not available on ksh88 and pdksh. On the more recent ksh93 (original AT&T Korn Shell) and mksh (currently actively developed pdksh derivative) it is, however, available. <<< is one of the “modern” shell extensions shared between ksh93, mksh, GNU bash and zsh. Your specific problem… read A B C <<< $line … can be ...


13

What happens is that bash replaces the tabs with spaces. You can avoid this problem by saying "$line" instead, or by explicitly cutting on spaces.


11

Maybe it will make sense if you rearrange the redirections a bit: <<< Hey > text.txt cat text.txt Hey is sent to stdin of cat, as a herestring. text.txt is opened for writing, and truncated. So if any text were in it, it would be gone. cat is executed with the argument text.txt. Since a file was provided as an argument, it ignores stdin, so ...


10

The problem is that you're not quoting $line. To investigate, change the two scripts so they simply print $line: #!/usr/bin/env bash while read line; do echo $line done < "$1" and #!/usr/bin/env zsh while read line; do echo $line done < "$1" Now, compare their output: $ bash.sh input foo bar baz foo bar baz $ zsh.sh input foo bar ...


9

I had added umask 777 before the here string. After removing the umask, the error went away. So lesson learned: There is a temporary file created for a here string (<<<), and this is related to a here document (<<), and you must have an appropriate umask set for these to work.


9

Yes, but you'd be using a an here-string rather than a here-document: cat >"$HOME/myRep/tiesto" <<<'tiesto' This will send the string tiesto to cat on its standard input, and it will write the string to the file $HOME/myRep/tiesto through a redirection of its standard output. Note that here-strings are not standard but are implemented by at ...


8

No, here-strings come from zsh in 2.0 in 1991 (and/or the Unix port of rc, their respective author exchanging ideas around that time, it's not clear which of the two had the idea or included it in his shell first). It was added to bash in 2.05b (2002), ksh93 in m+ (2002), mksh in R33 (2008), yash in 2.7 (2009). ksh88 is not getting any new features. Here ...


7

diff needs two file operands. With a here-string, you pass input to diff on its standard input. To make diff read from standard input, use - as the filename: $ diff file - <<<"$( sed 'expression' file )" or, more portably, $ sed 'expression' file | diff file - If you are using a shell that supports process substitutions with <(...), like ...


7

echo. Clearly less weird. #!/bin/bash a="`seq 10`" b="`seq 0 11`" diff <(echo "$a") <(echo "$b")


7

That's not the here string, it's ANSI-C quoting: Words of the form $'string' are treated specially. ... The expanded result is single-quoted, as if the dollar sign had not been present. So what you've got is a single-quoted string to the right of <<<. That string gets taken as the here string, with no further processing. There's no need to use ...


7

Here string is for shorter strings, here document for longer ones. The extra feature of here documents is that you can pass arbitrary text without having to worry about quoting. Just single-quote the delimiter, and make sure it does not show up in the text. You may use a random string (drawing from characters and digits), a technique that is also used to ...


6

In my case I altered the /tmp directory default permissions (I think I've changed by mistake to 0777). The solution was to revert it back to the default /tmp permission, which is 1777 in octal (1=sticky bit, 7=R+W+X). So in a nutshell sudo chmod -R 1777 /tmp should fix the problem.


6

For a pipe, the end of file is seen by the consumer(s) once all the producers have closed their file descriptor to the pipe and the consumer has read all the data. So, in: { echo foo echo bar } | cat cat will see end-of-file as soon as the second echo terminates and cat has read both foo\n and bar\n. There's nothing more for you to do. Things to bear ...


5

Is your script indented like that? the delimiter for the here-doc has to be at the beginning of the line. This works for me: #!/bin/bash echo $(cat <<EOF blah EOF )


4

The problem with your attempt is that what you call “the here-file method” simply doesn't exist. Here documents are a feature of the syntax of the shell programming language. They don't get interpreted by applications such as cat. Consider a shell script with a here document: cat <<EOF hello world EOF The way it works is that as part of parsing the ...


4

You don't need to write the cat line "the wrong way", this works just fine (though of course the arrows in the here-string still point in an odd direction): $ cat <<< "some text" >> testfile $ cat testfile some text As mentioned in the comments, the here-string adds a newline at the end, while with printf and echo you used \n in the front of ...


4

Leaving aside the fact that you could just printf "this\nthat\n" > /some/file, you can make a here-string with newlines with e.g. ANSI-C quoting: $ cat <<< $'this\nthat' this that Also, because of the quotes, this will try to create a file in a directory literally named *: cat > "/etc/php/*/zz_overrides.ini" This would work in Bash, but ...


3

s="myOutput"; grep -Fxqe "$s" < "$file" || printf "%s\n" "$s" >> "$file"


3

You need to use a herestring (<<<) here to pass the string as input to grep, herestring returns a file descriptor, grep can then operate on that: $ grep -ni "^li" <<<"linux loan litmus launch" Output: 1:linux 3:litmus If your shell doesn't support herestrings, many shells don't, you can print your string and pipe it to grep: $ echo "...


3

If you want to use a FIFO then you can do so, of course: script 1 FIFO_PATH="/path/to/fifo" exec 3<"$FIFO_PATH" # stalls until FIFO is opened for writing, too while read line; do : whatever done <&3 exec 3<&- : continue script script 2 FIFO_PATH="/path/to/fifo" exec 3>"$FIFO_PATH" # stalls until FIFO is opened for reading, too ...


3

The syntax of a here string is: <<< word where a word is a sequence of characters treated as a unit by the shell, delimited by whitespace. That could be a single regular word (hello), a single- or double-quoted string ('hello world', "hello world"), a parameter or command substitution ($foo, $(...)), something assembled with backslash escapes, or ...


2

If you quote EOF, variables won't be expanded, as you found out. This is documented in the Here Documents section of man bash: No parameter and variable expansion, command substitution, arithmetic expansion, or pathname expansion is performed on word. If any part of word is quoted, the delimiter is the result of quote removal on word, and ...


2

I think bash allow you to use a string with newlines directly, no need for a heredoc, or calling external commands (like cat): $ php_conf=' [PHP] post_max_size = 200M upload_max_filesize = 200M cgi.fix_pathinfo = 0 ' $ echo "$php_conf" [PHP] post_max_size = 200M upload_max_filesize = 200M cgi.fix_pathinfo = 0


2

It seems to me that you're wanting to loop through your array, reading the elements into columns: for ele in "${TEST_ARR[@]}" do read -r col1 col2 col3 col4 col5 col6 col7 col8 TRASH <<< "$ele" echo -e "${col1}\n${col2}\n${col3}\n${col4}\n${col5}\n${col6}\n" done


2

If the file does end in a newline, as all correct POSIX text files must, there is no need to add a newline before the text you add to the file. A way to make sure a file ends in a newline is to execute this: $ sed -i -e '$a\' file That will add a newline only if the file is missing the newline. Then, you can add the text you need with a trailing new line ...


2

From the manual: [n]<<<word The end is one word, not multiple words. So in this example, the first word is hello and terminates the here string. The next word is world, it is just an ordinary argument to cat, and cat assumes it is a file name to read. You could write it more clearly this way: $ cat world <<< hello


Only top voted, non community-wiki answers of a minimum length are eligible