1

If I have a file with three lines like this

line 1
line 2
curl -H 'Content-Type: application/json' -d '{"user": "joe"}' localhost/api

How can I execute a third line as command in bash?

I tried

$(sed '3q;d' file)

and

`sed '3q;d' file`

but it seems like in both cases the command is only partly executed, I don't get the right result. Of course, calling curl directly works fine.

Andrija Ćeranić
  • 1,633
  • 11
  • 14

3 Answers3

2

Unquoted expansion runs string-splitting and globbing, but not other stages of the parsing process. Thus, it doesn't honor quotes, redirections, or other expansions.

This is actually a Good Thing for security reasons -- think about what would happen if you had to worry about the string $(rm -rf ~) being present inside untrusted data that your scripts handle!

That said, if you entirely trust the contents of this file, you can use eval to run it through the entirety of the parsing process:

eval "$(sed '3q;d' file)"
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
0

How about running a bash subprocess, with the -c flag?

bash -c "$(sed '3q;d' file)"
salezica
  • 74,081
  • 25
  • 105
  • 166
0

From Bash 4 / Bash 3.2(Mac) or higher, you can source the file from a process substitution:

source <(sed '3q;d' file)

or shorter:

. <(sed '3q;d' file)
SLePort
  • 15,211
  • 3
  • 34
  • 44
  • Some versions of bash used to have a bug with this. (We have a StackOverflow question about that bug -- I can try to dig it up). – Charles Duffy Nov 10 '17 at 18:43
  • ...ahh, https://stackoverflow.com/questions/32596123/why-source-command-doesnt-work-with-process-substitution-in-bash-3-2; unfortunately, due to Apple's refusal to ship GPLv3'd software, such releases are still in wide use. – Charles Duffy Nov 10 '17 at 18:43
  • Hmm. Actually, it looks like Apple's latest 3.2.x release is patched for this, so maybe it's more historical now than I was thinking. :) – Charles Duffy Nov 10 '17 at 18:56
  • @CharlesDuffy Found in GNU Bash 2.05: "Startup files and files read with source or '.' are no longer required to be regular files." – SLePort Nov 10 '17 at 19:32
  • The bug *definitely* existed long past 2.05. See the linked SO questions, which were asked about 3.2 builds. – Charles Duffy Nov 10 '17 at 19:38
  • And http://lists.gnu.org/archive/html/bug-bash/2006-01/msg00018.html is a mailing list thread from the 3.1 days. – Charles Duffy Nov 10 '17 at 19:38
  • @CharlesDuffy You're right, I found a fix mentioned in [Bash 4.0rc1](http://lists.gnu.org/archive/html/bug-bash/2009-01/msg00029.html) release notes. – SLePort Nov 10 '17 at 19:47