63

I am very new to making bash scripts, but my goal here is to take a .txt file I have and assign the string of words in the txt file to a variable. I have tried this (no clue if I am on the right track or not).

#!/bin/bash
FILE="answer.txt"
file1="cat answer.txt"
print $file1

When I run this, I get

Warning: unknown mime-type for "cat" -- using "application/octet-stream"
Error: no such file "cat"
Error: no "print" mailcap rules found for type "text/plain"

What can I do to make this work?

Edit** When I change it to:

#!/bin/bash
    FILE="answer.txt"
    file1=$(cat answer.txt)
    print $file1

I get this instead:

Warning: unknown mime-type for "This" -- using "application/octet-stream"
Warning: unknown mime-type for "text" -- using "application/octet-stream"
Warning: unknown mime-type for "string" -- using "application/octet-stream"
Warning: unknown mime-type for "should" -- using "application/octet-stream"
Warning: unknown mime-type for "be" -- using "application/octet-stream"
Warning: unknown mime-type for "a" -- using "application/octet-stream"
Warning: unknown mime-type for "varible." -- using "application/octet-stream"
Error: no such file "This"
Error: no such file "text"
Error: no such file "string"
Error: no such file "should"
Error: no such file "be"
Error: no such file "a"
Error: no such file "varible."

When I enter cat answer.txt it prints out this text string should be a varible like it should but, I still can't get the bash to do that with the varible.

User97693321
  • 3,336
  • 7
  • 45
  • 69
BluGeni
  • 3,378
  • 8
  • 36
  • 64
  • 3
    As I said in my answer you're using print instead of echo. Also, you probably don't need the `FILE="answer.txt"` you're not using it anywhere. – Jeffrey Theobald Jan 02 '13 at 04:23
  • 1
    `print` is Korn shell, if using Bash you can only use `echo` (which is also supported by Korn shell). – cdarke Jan 02 '13 at 13:07

4 Answers4

94

In bash, $ (< answer.txt) is equivalent to $ (cat answer.txt), but built in and thus faster and safer. See the bash manual.

I suspect you're running this print:

NAME  
    run-mailcap, see, edit, compose, print − execute programs via entries in the mailcap file
mfaani
  • 33,269
  • 19
  • 164
  • 293
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • 8
    It's not really a shorthand. It's, according to the bash reference manual _equivalent by faster_. This is definitely _the_ answer to the OP. (It should be the accepted one). You should also mention how to print the expansion of `$file1`: `echo "$file1"`. – gniourf_gniourf Jan 02 '13 at 10:53
  • Nice catch that the error message really meant he typed "print" instead of "printf", which is what brought me here. – Ron Burk May 07 '15 at 16:27
  • 1
    That's not a shorthand but a builtin, therefore, it avoids shelling out to cat, and is thus much much faster. This should be the accepted answer. – Pourko Nov 23 '20 at 06:12
  • 6
    The full example is `file1="$(< answer.txt)"` – famzah Jan 06 '21 at 20:15
93

You need the backticks to capture output from a command (and you probably want echo instead of print):

file1=`cat answer.txt`
echo $file1
Jeffrey Theobald
  • 2,469
  • 18
  • 15
  • 15
    since this is marked as solution, please note that the use of `$(cat answer.txt)` is encouraged over the proposed solution since it works without special characters, is more readable and robust (e.g. supports more shells). cf: https://stackoverflow.com/a/4708569/160799 – Gregor Mar 05 '20 at 11:56
  • This will line breaks with a space and you end up with a single long line in the bash variable. –  Mar 10 '22 at 08:30
44

The $() construction returns the stdout from a command.

file_contents=$(cat answer.txt)
harpo
  • 41,820
  • 13
  • 96
  • 131
  • 2
    +1; more specifically, it is called command substitution: http://tldp.org/LDP/abs/html/commandsub.html – sampson-chen Jan 02 '13 at 04:10
  • 5
    That's not strictly speaking true. The result of this command is 0 (which is stored in $?), the **output** of this command is the contents of the file. – Jeffrey Theobald Jan 02 '13 at 04:10
0

Use command substitution with caution because it removes trailing new lines that makes the variable and the input file not identical, for example:

$ printf 'a\n\n' > input.txt
$ md5 < input.txt
94364860a0452ac23f3dac45f0091d81
$ x=$(cat input.txt)
$ printf %s "$x" | md5
0cc175b9c0f1b6a831c399e269772661
$ printf %s "$x" | od -ta
0000000    a                                                            
0000001

To make the file and the variable identical, add an extra byte and then remove it later:

$ x=$(cat input.txt && echo .)
$ x=${x%.}
$ printf %s "$x" | md5
94364860a0452ac23f3dac45f0091d81
$ printf %s "$x" | od -ta
0000000    a  nl  nl                                                    
0000003
Weihang Jian
  • 7,826
  • 4
  • 44
  • 55