0

Following is a source code which takes in only 'files',lists the file permissions of a file and prints the output by replacing

r=READ,w-WRITE,x-EXECUTABLE.

It should also echo "User".But the My problem here is that I have replaced '-' by User but then if the file has a permission of r--x,it also prints "User" @ that point.I know its not a correct way to go about it.Can anyone suggest me a better way of echoing "User".

I have also tried printing it before the loop but then it won't serve my purpose, as My program only works withe file permissions of a FILE and not any block/socket/pipe/directory/etc.

   #!/bin/bash

    if [ $# -lt 1 ];then
        echo "USAGE: $0 file-name"
        exit 1
    fi


    ls -l $1 | cut -c1-4 | tr "\012" "." > fp


    i=1

    while(($i <= 4))
    do
        p=`cat fp | cut -c$i`

        case $p in

        [dbsplc] | t) echo "not a file";
            exit 1;;
        -) echo "User";;
        r) echo "READ";;
        w) echo "WRITE";;
        x) echo "EXECUTE";;

        esac

        ((++i))
    done


    exit 0
1
  • When should you output "User"? Just when it's a regular file? Commented Oct 18, 2010 at 19:41

4 Answers 4

4

Too complicated. You don't have to rely on ls at all:

#!/bin/bash

if [[ $# -lt 1 ]]; then
    echo "USAGE: $(basename "$0") filename ..."
    exit 1
fi

exit_status=0

for file in "$@"; do
    if [[ ! -f "$file" ]]; then
        echo "not a file: $file" >&2
        exit_status=$(( exit_status + 1 ))
        continue
    fi

    echo "$file:"
    echo "User"   

    [[ -r "$file" ]] && echo "READ"
    [[ -w "$file" ]] && echo "WRITE"
    [[ -x "$file" ]] && echo "EXECUTE"
done

exit $exit_status
Sign up to request clarification or add additional context in comments.

Comments

1

I'd just use stat -c %a and process that instead.

2 Comments

Just note that stat isn't portable (BSD doesn't have it I think)
@Pavitar: Try yourself first, then ask further questions.
0

an exemple using awk (easily adaptable to your program)

ll |awk '{
             rights=substr($1, 2, 3);
             sub(/r/, "READ ", rights);
             sub(/w/, "WRITE ", rights);
             sub(/x/, "EXECUTE ", rights);
             print rights $3
          }'

Explanations :

rights=substr($1, 2, 3);

$1 contains rights of your program and we only takes the 3 first rights (user one)

sub(/r/, "READ ", rights);

Substiture "r" with READ in rights (and so on).

print rights $3

Print rights (substituated) and $3 that contains the user name.

Comments

0

This served my purpose,I separated the first condition into a different case-statement.:

#!/bin/bash

if [ $# -lt 1 ];then
    echo "USAGE: $0 file-name"
    exit 1
fi


ls -l $1 | cut -c1-4 | tr "\012" "." > fp


i=1
while(($i == 1))
do
    p=`cat fp | cut -c$i`

    case $p in

    [dbsplc] | t) echo "not a file";
        exit 1;;
esac

     echo "User"
    ((++i))
done



while(($i <= 4))
do
    p=`cat fp | cut -c$i`

    case $p in
    r) echo "READ";;
    w) echo "WRITE";;
    x) echo "EXECUTE";;

    esac

    ((++i))
done


exit 0

2 Comments

There's absolutely no reason to use the first while - it's always going to be executed and only once. The second while should be a for loop instead: for i in {2..4}. It's not necessary to use cat. In fact, the temporary file and all the external utilities are also unnecessary since you can save the data in a variable and use Bash's substring parsing to pick out the individual characters ${var:i:1}. However, glenn jackman's answer is the way to go.
@ Dennis Williamson -- OK.I'm a novice.So I did what I thought was simple for me to understand.I will surely try Glenn Jackman's approach as well.Thankyou for the tips ..

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.