0

I have a text file (test.txt) whose contents are:

mplayer -fs video.avi -vf mirror

If I execute:

eval "$(cat test.txt)"

I get:

 doesn't exist.or
Error parsing option on the command line: -vf
MPlayer 1.1-4.8 (C) 2000-2012 MPlayer Team

But if I execute:

mplayer -fs video.avi -vf mirror

the video will be played.

Why does eval (or mplayer?) fail in this case?

I ran:

$ file test.txt
test.txt: ASCII text, with CRLF line terminators

The text file seems to be created under Windows. I copied its contents and created a new file under Linux. Now it works.

But how to get it working with the original Windows file? Do I have to replace some characters?

ka3ak
  • 2,435
  • 2
  • 30
  • 57
  • Why do you use `eval`? do you really need to execute the content in the current shell? in that case, _source_ it with `. test.txt` otherwise, execute it with `bash test.txt`. – gniourf_gniourf Dec 23 '16 at 12:23
  • It is not clear to me in which scenario `eval` might be better than simply `bash test.txt` or `. test.txt`. Could you elaborate more? – Dario Dec 23 '16 at 12:29
  • For how to make it work with the line endings see [here](http://stackoverflow.com/questions/16768776/convert-line-endings) you have to remove the `\r` carriage returns – Eric Renouf Dec 23 '16 at 12:35

2 Answers2

1

Just use tr to strip off the windows CRLF file endings and convert it to UNIX line termination strings

tr -d '\015' <file_with_DOS_endings >file_UNIX_endings

To run your original command in with the above logic invoke an explicit sub-shell with the -c flag,

bash -c "$(tr -d '\15\32' < "test.txt")"
Inian
  • 80,270
  • 14
  • 142
  • 161
  • Yes. I've just noticed that it works, if I execute: eval "$(cat test.txt | tr -d '\15\32')". Change your answer to include this command and I'll accept it. I don't want to create an additional file during the process. – ka3ak Dec 23 '16 at 12:37
  • @ka3ak: I have removed the useless use of cat and explicit use of eval. – Inian Dec 23 '16 at 12:42
  • You are too quick :) When I saw that your answer was correct (and worked!) I accepted it, but now it is again incorrect. – ka3ak Dec 23 '16 at 12:44
  • Try to execute your second command. bash needs -c option in this case! – ka3ak Dec 23 '16 at 12:47
0

Shells don't like files with Windows/DOS line endings. They treat the carriage return ('\r') as part of the last word.

Worse, when a carriage return is output as part of an error message, it places the cursor at the beginning of the line, causing previous message text to be overwritten. This explains the garbled message.

To run a shell script stored in a file, you simply make it executable (chmod +x test.txt), then ./test.txt. No need for eval.

You can convert DOS files to Unix files with

dos2unix test.txt

to remove the carriage returns.

Jens
  • 69,818
  • 15
  • 125
  • 179