0

I have a simple script that uses a for loop where I want to take the value of a variable and assign it to another command and kill the screen. The script goes as

#!/usr/bin/sh/
echo 'I am going to kill the screens now';
for j in $(seq 1 1 10)
do
    i=$(grep -oP '.*?(?=\.)');
    echo $i
    screen -S $i -p 0 -X quit 
done <file1.txt
echo 'exiting...'

file1.txt

There are screens on:

    4974.eth2   (Detached)
    5105.eth11  (Detached)
    4990.eth3   (Detached)
    5006.eth5   (Detached)
    5054.eth8   (Detached)
    5070.eth9   (Detached)
    5038.eth7   (Detached)
    5022.eth6   (Detached)
8 Sockets in /var/run/screen/S-root.

So here, I am iterating through 10 lines and assigning the value of i=whatever before a period(.). eg. 4974. Then placing 4974 in screen command and killing it. The problem here is, it is reading and grepping all the lines at a time and in the value of i it places as 4974 5105 4990 5006 5054 5070 5038 5022 in the screen command and it obviously it cannot find a screen id like that and doesn't kill any screen. How do i iterate the loop such that at a time it takes one id ie.value of i=4974 and place only that in the screen command so that it will kill it.. Let me know if you understand my question correctly.

4
  • for i in $(grep -oP ...); do Commented Sep 3, 2014 at 21:43
  • 1
    also, don't use seq -- it's not a standard command, not part of bash, and there's no guarantee it'll be available on any given operating system. for ((j=1; j<=10; j++)) is the equivalent that works anywhere bash is installed. Commented Sep 3, 2014 at 21:45
  • You don't use $j anywhere, and you already get the effect of looping by iterating over the results from grep -- why do you have it at all? Commented Sep 3, 2014 at 21:47
  • Also consider read -r -a ids < <(grep -oP ...); for pid in "${ids[@]}"; do ...; done -- that way you get the list of IDs stored in an array. Commented Sep 3, 2014 at 21:48

2 Answers 2

1

Instead of iterating over a counter, iterate over your results directly:

set -f # disable globbing, so globs in grep's output aren't expanded
echo 'I am going to kill the screens now' >&2
for i in $(grep -oP '.*?(?=\.)'); do
    echo "$i"
    screen -S "$i" -p 0 -X quit 
done <file1.txt
echo 'exiting...' >&2
Sign up to request clarification or add additional context in comments.

Comments

1

Try this:

awk -F'[. ]+' '/Detached/ {print $2}' file.txt | while read i
do
    echo "$i"
    screen -S "$i" -p 0 -X quit 
done

5 Comments

Needs more quotes -- echo "$i", -S "$i"
...and using read -r absent a compelling reason to do otherwise is best practice.
When you know that the input data is in a strict format like this, you don't need precautions like that. That's mainly necessary when dealing with free-form input from users.
charles and Barmar..Thanks for the answers.I tried the first one which Charles had mentioned. for i in $(grep -oP '.*?(?=\.)') and it worked like a charm.
@Barmar, screen socket names can be user-specified, so precautions are still called for.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.