You are not logged in.

#1 2022-01-31 22:12:36

fcon
Member
Registered: 2022-01-31
Posts: 9

How do I run one line of a text file in a bash script?

I've been working on this script for hours, and looking through several search results. I've tried "source <$(sed -n "$linenumber"p numbers)" (numbers being the target text file) and it gives an ambiguous redirect error, I've tried "$($(sed -n "$linenumber"p numbers))" which gives a "command not found" error when it comes across the variables I've set (bash: a=1,: command not found), and "$(sed -n "$linenumber"p numbers) | bash" works, sort of, as variables aren't kept. This includes the linenumber variable, and so running that was basically a fork bomb.

Sorry if this is a newbie question, but what else can I try in this case?

Offline

#2 2022-01-31 22:23:07

karabaja4
Member
From: Croatia
Registered: 2008-09-14
Posts: 950

Re: How do I run one line of a text file in a bash script?

This works fine for me in bash:

~ >> printf '%s\n%s\n%s\n%s\n' "one" "echo a" "three" "four" > numbers
~ >> $(sed -n 2p numbers)
a

Not sure what you mean by "variables aren't kept". How they can be kept if you are only running one line?

Last edited by karabaja4 (2022-01-31 22:23:26)

Offline

#3 2022-01-31 22:38:22

lambdarch
Member
Registered: 2021-01-10
Posts: 46

Re: How do I run one line of a text file in a bash script?

source <(sed -n "$linenumber"p numbers)

This is a process substitution.
Commands in a pipe are executed in subshells, that's why variables aren't kept.

Offline

#4 2022-01-31 22:50:15

fcon
Member
Registered: 2022-01-31
Posts: 9

Re: How do I run one line of a text file in a bash script?

karabaja4 wrote:

This works fine for me in bash:

~ >> printf '%s\n%s\n%s\n%s\n' "one" "echo a" "three" "four" > numbers
~ >> $(sed -n 2p numbers)
a

Not sure what you mean by "variables aren't kept". How they can be kept if you are only running one line?

This was just part of the script, the part that was giving me trouble. The rest seems like it'll work fine if I fix this. As for your snippet, how exactly does it work? I'm unsure as to how I'd adapt it to what I'm running.

lambdarch wrote:
source <(sed -n "$linenumber"p numbers)

This is a process substitution.
Commands in a pipe are executed in subshells, that's why variables aren't kept.

That specific one never worked at all, instead giving me an ambiguous redirect error, I was referring to "$(sed -n "$linenumber"p numbers) | bash" when mentioning variables not being kept. Good to know that it wouldn't have worked even if I got it running, though.

Offline

#5 2022-01-31 22:55:53

lambdarch
Member
Registered: 2021-01-10
Posts: 46

Re: How do I run one line of a text file in a bash script?

Are you sure?

source <(sed -n "$linenumber"p numbers)

is different from

source <$(sed -n "$linenumber"p numbers)

And I was also referring to

$(sed -n "$linenumber"p numbers) | bash

when mentioning variables not being kept.
Variables are kept in the first command line above : sed is executed in a subshell, but the sourcing takes place in the current environment.

Last edited by lambdarch (2022-01-31 22:57:09)

Offline

#6 2022-01-31 23:41:31

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 26,733
Website

Re: How do I run one line of a text file in a bash script?

sourcing the result of process substitution doesn't make much sense.  It should work, but what it's doing is having sed generate a command, then using a subshell to make that command appear to be in a file, and then using 'source' to pretend the content of that fake-file is a command.  Remove all the middlemen:

eval $(sed -n ${linenumber}p numbers)

Without the "eval" (as in the first response) you will not be able to use shell builtins but only run external binaries (if the line in "numbers" is a binary command like "ls" it will work, but "a=3" would not).

However, I'm curious about the context or purpose - I strongly suspect this is an X-Y problem.


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#7 2022-02-01 00:53:05

fcon
Member
Registered: 2022-01-31
Posts: 9

Re: How do I run one line of a text file in a bash script?

Trilby wrote:

sourcing the result of process substitution doesn't make much sense.  It should work, but what it's doing is having sed generate a command, then using a subshell to make that command appear to be in a file, and then using 'source' to pretend the content of that fake-file is a command.  Remove all the middlemen:

eval $(sed -n ${linenumber}p numbers)

Without the "eval" (as in the first response) you will not be able to use shell builtins but only run external binaries (if the line in "numbers" is a binary command like "ls" it will work, but "a=3" would not).

However, I'm curious about the context or purpose - I strongly suspect this is an X-Y problem.

It's a mass quadratic equation solver. This is what I have so far, plus the numbers file, both updated to use eval like you suggested. Not exactly the best, especially since in its current state it's just a forkbomb that spits out syntax errors. I'm aware it presents the equation in a weird way, that's intentional. I made it echo the variables used for debugging purposes. It's likely obvious, but this is my first time doing a script of this level, I just did it for a bit of practice thinking it would be easy.

Offline

#8 2022-02-01 01:00:29

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 26,733
Website

Re: How do I run one line of a text file in a bash script?

Why do you have "eval" commands in the numbers file?  And what do you expect it to do?  You are setting variables, then piping to an eval command, but there is no output from setting variables, so there is nothing to pipe!  Did you *add* those eval commands to the numbers file based on my suggestion - that's not at all what I meant.

Why put shell commands in "numbers" anyways?  That looks like it's meant to be a data file, so make it a data file.  I suspect you want something like this:

while read a b c; do
   # insert all your code here to work with variables $a $b and $c
done < numbers

And just make the numbers file a data table:

1   -5   -3
2    5    3

Also note that you don't need to use two subshells and "bc" to increment a number in the shell, the following lines all have the same effect (but none of them are needed if you use the loop above):

# awkward:
linenumber=$(echo "$linenumber + 1" | bc)
#  better:
linenumber=$((linenumber + 1))
# also good:
let linenumber++

Last edited by Trilby (2022-02-01 01:14:00)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#9 2022-02-04 23:45:15

fcon
Member
Registered: 2022-01-31
Posts: 9

Re: How do I run one line of a text file in a bash script?

I had no idea Bash supported tables. This makes things a whole lot easier. Thanks!

Last edited by fcon (2022-02-04 23:45:32)

Offline

#10 2022-02-04 23:49:28

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 26,733
Website

Re: How do I run one line of a text file in a bash script?

Bash doesn't "support tables" itself.  But it can read files and can read in variables separated by whitespace.  So putting those together it is trivial to have a script read tabular (and / or whitespace-delineated) data.

Last edited by Trilby (2022-02-04 23:52:10)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

Board footer

Powered by FluxBB