0

Im trying to put the contents of a awk command in to a bash array however im having a bit of trouble.

>>test.sh
f_checkuser() {
    _l="/etc/login.defs"
    _p="/etc/passwd"
    ## get mini UID limit ##
    l=$(grep "^UID_MIN" $_l)
    ## get max UID limit ##
    l1=$(grep "^UID_MAX" $_l)
    awk -F':' -v "min=${l##UID_MIN}" -v "max=${l1##UID_MAX}" '{ if ( $3 >= min && $3 <= max  && $7 != "/sbin/nologin" ) print $0 }' "$_p"
}
...

Used files:

Sample File: /etc/login.defs

>>/etc/login.defs
### Min/max values for automatic uid selection in useradd
UID_MIN          1000
UID_MAX         60000

Sample File: /etc/passwd

>>/etc/passwd
root:x:0:0:root:/root:/usr/bin/zsh
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
admin:x:1000:1000:Administrator,,,:/home/admin:/bin/bash
daniel:x:1001:1001:Daniel,,,:/home/daniel:/bin/bash

The output looks like:

admin:x:1000:1000:Administrator,,,:/home/admin:/bin/bash
daniel:x:1001:1001:User,,,:/home/user:/bin/bash

respectively (awk ... print $1 }' "$_p")

admin
daniel

Now my problem is to save the awk output in an Array to use it as variable.

>>test.sh
...
f_checkuser

echo "Array items and indexes:"
for index in ${!LOKAL_USERS[*]}
do
    printf "%4d: %s\n" $index ${array[$index]}
done

It could/should look like this example.

Array items and indexes:
   0: admin
   1: daniel

Specially i would become all Users of a System (not root,bin,sys,ssh,...) without blocked users in an array. Perhaps someone has another idea to solve my Problem?

Chimaira
  • 11
  • 2
  • 2
    Post some sample input (the contents of `/etc/login.defs` and `/etc/passwd`) and expected output fro that input. Make it something we can test a potential solution against. You do not need all those shell variables and greps - just one simple awk command will do it. – Ed Morton Sep 12 '15 at 21:33

3 Answers3

1

Are you trying to set the output of one script to an array? There is a bash has a way of doing this. For example,

a=( $(seq 1 10) ); echo ${a[1]}

will populate the array a with elements 1 to 10 and will print 2, the second line generated by seq (array index starts at zero). Simply replace the contents of $(...) with your script.

karakfa
  • 66,216
  • 7
  • 41
  • 56
0

For those coming to this years later ...

bash 4 introduced readarray (aka mapfile) exactly for this purpose.

See also Bash capturing output of awk into array

peak
  • 105,803
  • 17
  • 152
  • 177
-2

One solution that works:

array=()
f_checkuser(){
        ...
        ...
        tempfile="localuser.tmp"
        touch ${tempfile}
        awk -F':'...'{... print $1 }' "$_p" > ${HOME}/${tempfile}
        getArrayfromFile "${tempfile}"
}
getArrayfromFile() {
    i=0
    while read line # Read a line
    do
        array[i]=$line # Put it into the array
        i=$(($i + 1))
    done < $1
}

f_checkuser

echo "Array items and indexes:"
for index in ${!array[*]}
do
    printf "%4d: %s\n" $index ${array[$index]}
done

Output:

Array items and indexes:
   0: daniel
   1: admin

But I like more to observe without a new temp-file. So, have someone any another idea without a temp-file?

Chimaira
  • 11
  • 2
  • 1
    I already told you what you need to do in order for us to be able to help you. Please re-read my previous comment. – Ed Morton Sep 12 '15 at 22:16
  • 2
    Last time - post something we can test a possible solution against. Right now your input file has a bunch of `...`s that I'm sure aren't really present in your actual input file so get rid of those, and your output contains a line for `user` that doesn't exist in your input file. Clean it up to make it precise and TESTABLE. The more effort you put into your question the better chance someone will help you with an answer and that answer will be correct. – Ed Morton Sep 13 '15 at 15:38