0
$ cat foo.txt
a=1one
b=2two
c=3 three
d=4four

$ source foo.txt
bash: three: command not found...

Need to set all the variable listed in foo.txt, how to source this file by escaping the space character? foo.txt comes from other application, which I cannot control, or is there an alternative to source ?

rodee
  • 3,233
  • 5
  • 34
  • 70
  • @anubhava, ...if you trust it. If you don't, much better to explicitly parse. – Charles Duffy Jul 25 '19 at 18:07
  • @anubhava, is there a command line option with sed you proposed? or should I create a sed'ed file and source that new file? – rodee Jul 25 '19 at 18:10
  • @rodee, `sed -i` modifies a file in-place (well, in theory; actually, it creates a new temporary file and renames it over the original). If you have a baseline POSIX `sed` that doesn't support it, then yes, you can leave that option out, redirect output to a file, and source that file (or, if you have a new enough bash that this isn't buggy, `source <(sed ...)` -- though that has the same security problems that `source` has altogether, so I don't recommend it). – Charles Duffy Jul 25 '19 at 18:11
  • @anubhava, what's the significance of whitespace before '*' in your first comment, `s/ *$/"/`, sourcing fails if I remove this whitespace, but I don't understand why. – rodee Jul 25 '19 at 19:09
  • `*` in regex is a modifier meaning "zero-or-more of the prior thing", in this case, meaning zero or more spaces. If there is no prior thing, it's invalid syntax. – Charles Duffy Jul 25 '19 at 19:36
  • Thanks Charles, yes, that was my understanding too, but there is no space at the end of line(before `$`) in `foo.txt`, so how is it working? – rodee Jul 25 '19 at 19:43
  • Why wouldn't it work? Zero spaces can be matched by a pattern that looks for "zero-or-more spaces", after all, because zero is in the set of zero-or-more. – Charles Duffy Jul 25 '19 at 19:49
  • oops yes, stupid me, thanks a lot. – rodee Jul 25 '19 at 19:56

1 Answers1

-1

If the output is so regular, you could try to preprocess the file using sed like this:

$ sed -e "s/=/='/;s/$/'/" < foo.txt >sourced.env

and then source sourced.env. This will add a ' just after the = and add an ending '.

Diego Sevilla
  • 28,636
  • 4
  • 59
  • 87
  • If we don't trust the program writing the file, this is a very bad idea; if it contains `foo=$(rm -rf ~)'$(rm -rf ~)'`, then the literal quotes inside the file will cancel out the ones added by `sed`. – Charles Duffy Jul 25 '19 at 18:09
  • I can trust that file. – rodee Jul 25 '19 at 18:11
  • 1
    Mmm. Be sure. At one of my former employers they trusted filenames to be safely generated, until a buffer overflow in a 3rd-party C library used by the Python script that was generating content dumped random content from memory into the names, which happened to contain a whitespace-surrounded asterisk; an unsafely-written script tried to delete the file, and Bad Things happened. Which is to say -- weird things happen, sometimes; it's better to write safe code even when you don't think you need to, and then you're doing things the right way when it *does* matter, expectedly or otherwise. – Charles Duffy Jul 25 '19 at 18:13