Issue in shell scripting
The below coding is to find who are all the user having home directory
for (( a=1; a<=$#; a++ )) do ls /home | grep $$a >>/dev/null if [[ $? -eq 0 ]] then echo $$a is having home dir else echo $$a is not having home dir fi done Note: Here i am trying to pass usernames as a parameter. Output: 6712a is having home dir Issue: $$a is not taking my parameter value. it is taking $$ as a process ID (6712). I want to check $1, $2, $3, etc using $$a. I tried by using brace like $($a), ${$a}, etc. But it is not working. Kindly help me to resolve this issue. |
It took me a while to understand what you were trying to accomplish with that for loop, but I think I get it now: You want the loop to iterate though the command line parameters, and then refer to a specific parameter variable, say "$1", inside the loop using a syntax like $${a}, am I right?
The problem is related to the way parameters are expanded. You want "$${a}" to expand to something like "$1" or "$2" initially, with 1 or 2 being the value of $a, and then you want the shell to expand the actual parameter variable ($1 or $2, depending on the value of $a). As you've seen, that's doesn't work. While some clever coding using delayed expansion might work, may a suggest an alternative approach? How about focusing on $1 and then use shift to iterate through the command line arguments? Just create a loop that runs while $1 is non-null, and inside that loop, check for the existence of a home directory and run shift at the end: Code:
while ! [ "$1" == "" ]; do This way, you'll be able to handle any number of command line arguments, which I'd argue is an improvement on your initial approach which may be limited to 9, depending on which shell you're using. |
Picking at nits, again...
It may be worthwhile to note that this only finds users with home folders directly under /home.
I run systems where some sets of users may have home folders in different locations. Were that an issue, parsing /etc/passwd for accounts with value UID in the user range, and detecting the home folder field, and testing its validity and existance would be a more rigerous solution. That may be far beyond the need here, just thought I should mention it. And that even that method could be 'fooled' by some unexpected non-user accounts in high UID space. |
Quote:
Due to the use of $$, the output is showing me PID. Actual output: $$a--> {$$}a --->{6712}a ----> 6712a ---> showing PID plus 'a' Expecting output $$a---> ${$a} --->${1} ---> $1 ---> 1st parameter value it would be helpful for me, if you let me know the proper syntax to get above result. Thank you!! |
Quote:
|
Quote:
Quote:
You can code around it with eval if you like: eval echo \$${a} ---> eval echo $1 ---> echo (1st parameter value) The first expansion returns a literal $ character (due to the backslash escape) followed by the contents of the variable $a. Then echo $1 is evaluated, returning the contents of $1. In general, using eval is not a recommended practice since it basically just runs whatever you pass it. If you make a simple mistake or a malicious user is able to manipulate the input to embed a command, you may end up executing said command and compromise the system. Anyway, here's how it might work: Code:
for (( a=1; a<=$#; a++ )) do As for locating a user's home directory by searching through /etc/passwd, that may not be such a good idea. It will work on most standalone systems, but will fail if the user account is stored in a database. A (much) better approach would be to parse the output from getent passwd. It returns user information in exactly the same format as used by the /etc/passwd file, but it fetches that information from whichever source the system is configured to use, be that /etc/passwd, NIS, Active Directory/winbind, an LDAP server, or something else entirely. Here's a version of my code using getent: Code:
while ! [ "$1" == "" ]; do Code:
for (( a=1; a<=$#; a++ )) do |
nice!
Listen to Ser Olmy, he has excellent taste.
I was wondering about that use of grep though, I think another solution may serve better: using the above solution without eval but in my style. Code:
while [[ -n "$1" ]]; do I added a test for real users simply because I cannot leave well enough alone. Ever. And Ser Olmy may know a better way. |
To use the value of a bash variable to point to another variable you don't need to use eval you can do sort of 'c' type pointer like so:
Code:
AVAR="some text" |
All times are GMT -5. The time now is 11:08 PM. |