From: Bill Marcum on
On 2010-04-09, houghi <houghi(a)houghi.org.invalid> wrote:
> I have the following script:
> #v+
> #!/bin/bash
> set -x
> COUNT=0
> youtube-dl -g -e -b $URL |while read LINE
> do
> if [ "$COUNT" == "0" ]
> then
> TITLE=$LINE
> COUNT=1
> else
> LINK=$LINE
> echo $LINK
> fi
> done
> echo ${TITLE}.flv
> echo $LINK
> #v-
>
>
> My question is why does it do the echo with the first $LINK but not with
> the second? As far as I can see LINK gets a value (as well as TITLE),
> yet at the end they are somehow empty. What am I doing wrong?
>
The loop is in a pipe, so it's in a subshell.


--
The culpability of a female or oneself is a matter of opinion, however.
-- ¬R
From: pk on
houghi wrote:

> Bill Marcum wrote:
>> On 2010-04-09, houghi <houghi(a)houghi.org.invalid> wrote:
>>> I have the following script:
>>> #v+
>>> #!/bin/bash
>>> set -x
>>> COUNT=0
>>> youtube-dl -g -e -b $URL |while read LINE
>>> do
>>> if [ "$COUNT" == "0" ]
>>> then
>>> TITLE=$LINE
>>> COUNT=1
>>> else
>>> LINK=$LINE
>>> echo $LINK
>>> fi
>>> done
>>> echo ${TITLE}.flv
>>> echo $LINK
>>> #v-
>>>
>>>
>>> My question is why does it do the echo with the first $LINK but not with
>>> the second? As far as I can see LINK gets a value (as well as TITLE),
>>> yet at the end they are somehow empty. What am I doing wrong?
>>>
>> The loop is in a pipe, so it's in a subshell.
>
> So what is the solution? I could write the values to a temporary file,
> but I like to avoid that. So the obvious solution would be not to use a
> pipe.
>
> What I actualy want is the following: `youtube-dl -g -e -b $URL` gives
> me output in two lines. The first line will have a lot of spaces in it.
> $TITLE should get that value. The second line won't have any spaces in
> it. $LINK should get that value.

Since you're using bash, you can use process substitution and avoid the
pipe, so no subshell is created:

COUNT=0
while read LINE
do
if [ "$COUNT" == "0" ]
then
TITLE=$LINE
COUNT=1
else
LINK=$LINE
echo $LINK
fi
done < <(youtube-dl -g -e -b "$URL")

echo ${TITLE}.flv
echo $LINK

(I'm not saying anything about quoting, style etc. here)
From: pk on
houghi wrote:

> pk wrote:
>> Since you're using bash, you can use process substitution and avoid the
>> pipe, so no subshell is created:
>
> Thanks. I will read up on "process substitution" as I never had heard
> about it before. So double thanks.

This is also a bash FAQ:

http://mywiki.wooledge.org/BashFAQ/024

From: Geoff Clare on
houghi wrote:

> Bill Marcum wrote:
>> On 2010-04-09, houghi <houghi(a)houghi.org.invalid> wrote:
>>> I have the following script:
>>> #v+
>>> #!/bin/bash
>>> set -x
>>> COUNT=0
>>> youtube-dl -g -e -b $URL |while read LINE
>>> do
>>> if [ "$COUNT" == "0" ]
>>> then
>>> TITLE=$LINE
>>> COUNT=1
>>> else
>>> LINK=$LINE
>>> echo $LINK
>>> fi
>>> done
>>> echo ${TITLE}.flv
>>> echo $LINK
>>> #v-
>>>
>>>
>>> My question is why does it do the echo with the first $LINK but not with
>>> the second? As far as I can see LINK gets a value (as well as TITLE),
>>> yet at the end they are somehow empty. What am I doing wrong?
>>>
>> The loop is in a pipe, so it's in a subshell.
>
> So what is the solution?

Include the commands after the loop in the subshell:

COUNT=0
youtube-dl -g -e -b $URL | {
while read LINE
do
if [ "$COUNT" == "0" ]
then
TITLE=$LINE
COUNT=1
else
LINK=$LINE
echo $LINK
fi
done
echo ${TITLE}.flv
echo $LINK
}

You should also get into the habit of using printf instead of echo
(except maybe for simple fixed strings), and quoting variables.
E.g.
printf '%s\n' "$LINK"

--
Geoff Clare <netnews(a)gclare.org.uk>


From: Ed Morton on
On 4/9/2010 7:59 AM, Geoff Clare wrote:
> houghi wrote:
>
>> Bill Marcum wrote:
>>> On 2010-04-09, houghi<houghi(a)houghi.org.invalid> wrote:
>>>> I have the following script:
>>>> #v+
>>>> #!/bin/bash
>>>> set -x
>>>> COUNT=0
>>>> youtube-dl -g -e -b $URL |while read LINE
>>>> do
>>>> if [ "$COUNT" == "0" ]
>>>> then
>>>> TITLE=$LINE
>>>> COUNT=1
>>>> else
>>>> LINK=$LINE
>>>> echo $LINK
>>>> fi
>>>> done
>>>> echo ${TITLE}.flv
>>>> echo $LINK
>>>> #v-
>>>>
>>>>
>>>> My question is why does it do the echo with the first $LINK but not with
>>>> the second? As far as I can see LINK gets a value (as well as TITLE),
>>>> yet at the end they are somehow empty. What am I doing wrong?
>>>>
>>> The loop is in a pipe, so it's in a subshell.
>>
>> So what is the solution?
>
> Include the commands after the loop in the subshell:
>
> COUNT=0
> youtube-dl -g -e -b $URL | {
> while read LINE
> do
> if [ "$COUNT" == "0" ]
> then
> TITLE=$LINE
> COUNT=1
> else
> LINK=$LINE
> echo $LINK
> fi
> done
> echo ${TITLE}.flv
> echo $LINK
> }
>
> You should also get into the habit of using printf instead of echo
> (except maybe for simple fixed strings), and quoting variables.
> E.g.
> printf '%s\n' "$LINK"
>

You could alternatively do:

youtube-dl -g -e -b "$URL" |
awk '{out = (NR==1 ? $0 ".flv" : out ORS $0)} END{print out ORS $0}'

if you really want the output as from your posted script, which I think might
actually contain some debugging lines. If you want something different, tell us
what you're really trying to do.

Regards,

Ed.