-2

I'm trying to get the below to take usernames from the 'users' file identified and for each line, (cd ~$user) and check for a .subscriptions file, if there, less that output into a file under data.

 #!/bin/bash
  2 
  3 
  4 
  5 data=/usr2/c/subscription/userdata
  6 users=`cat /usr2/c/subscription/users`
  7 
  8 for i in $users
  9 do
 10 cd ~$i
 11 if 
 12         (test .subscriptions)
 13 then
 14         less .subscriptions >> $data
 15 else 
 16         echo "didn't run"
 17 fi
 18 done
Jahid
  • 21,542
  • 10
  • 90
  • 108
Dimos
  • 35
  • 4
  • `(test .subscriptions)` is always going to return true -- it looks at whether `.subscriptions` is a non-empty string, not at whether a file under that name exists. – Charles Duffy May 19 '16 at 17:45
  • And `cd ~$i` isn't valid bash (or POSIX sh) syntax to expand the named user's home directory. – Charles Duffy May 19 '16 at 17:45
  • 1
    It seems you forgot to include a question in your question. – Biffen May 19 '16 at 17:46
  • 1
    and `less` is a tool for displaying data to users, not... whatever it is you want it to do here. – Charles Duffy May 19 '16 at 17:46
  • 1
    ...so, I'd argue that you have a bunch of different questions you should be asking individually (if they aren't already asked and answered elsewhere in the knowledge base). One of them is how to look up a named user's home directory in bash. – Charles Duffy May 19 '16 at 17:47
  • Sorry, I'm failing to understand how to get into each line of the '$users' file and check for the .subscriptions file to output, if exists, to '$data' – Dimos May 19 '16 at 17:47
  • so, in terms of how to read a file line-by-line, see http://mywiki.wooledge.org/BashFAQ/001, and http://mywiki.wooledge.org/DontReadLinesWithFor – Charles Duffy May 19 '16 at 17:48
  • on how to look up a user's home directory, how to do that actually depends on your security constraints -- the easy approach, `eval "echo ~$user"`, is risky if you don't trust your data. – Charles Duffy May 19 '16 at 17:49
  • ...see http://stackoverflow.com/questions/3963716/how-to-manually-expand-a-special-variable-ex-tilde-in-bash for an in-depth discussion of that question. (I have my own answer there, but also endorse the one at http://stackoverflow.com/a/30770111/14122). – Charles Duffy May 19 '16 at 17:50
  • Ok, excellent and all great information! I will take a look at the links and read on. Much appreciated for the guidance. – Dimos May 19 '16 at 17:51
  • 2
    Please update your question so that it actually asks a question. – Keith Thompson May 19 '16 at 18:09

2 Answers2

0

Probably what you want is:

#!/bin/bash

#Note: using common directory saves me characters later!
usrDir=/usr2/c/subscription;
datFl=${usrDir}/userdata

#No need to read to variable just use subshell for loop input.
for u in $( cat ${usrDir}/users ); do
   subFl=~${u}/.subscriptions
   if [ -a $subFl ]; then
      cat $subFl >> $datFl
   else 
      echo "didn't run"
   fi
done
  1. Notice as others pointed out, test is not the command you want to check for the file. You could use test -e, but [ -a $flName ] is the preferred syntax for BASH.

  2. You probably don't want to use less ... an interactive command on ~{u}/.subscriptions... you probably wantcat`.

  3. It's unnecessary to cd to the ~${u} directory.

Also if for some reason you expand the code and it makes sense to store the users as an array variable your syntax is a bit off. In that case you would use:

#!/bin/bash
usrDir=/usr2/c/subscription;
datFl=${usrDir}/userdata
users=( $( cat ${usrDir}/users ) )
for u in ${users[@]}; do
   ...
done

The outer () corresponds to array assignment. i.e. to assign an array of string literals you can do

users=( jim bob jones )

The inner $() which is also used in my solution above is a subshell.

See (Advanced Bash-Scripting Guide):
7.2. File test operators
Chapter 21. Subshells
Chapter 27. Arrays

How to properly use test:
The classic test command

Jason R. Mick
  • 5,177
  • 4
  • 40
  • 69
  • Thank you for the information! You guys are great! I am novice at this and the pointers from this site and networks are amazing. – Dimos May 19 '16 at 18:49
0

Quick&dirty

#!/bin/bash
homedir() { $SHELL -c "cd ~$1 && pwd" 2>/dev/null; }
file=.subscriptions
while read -r user
do
        hd=$(homedir $user)
        [[ -z "$hd" ]] && continue;
        [[ -f "$hd/$file" ]] || continue
        cat "$hd/$file"
done

use it as

this_script.sh < list_of_users.txt > output_file.txt
clt60
  • 62,119
  • 17
  • 107
  • 194