Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I am in the only Linux class offered at my school, and there is an assignment that is driving me nuts. I have to create a bash script that has a function that can be called recursively to scan the directory specified in the first argument, and list the any file with the setuid in ls -l format. If another directory is found the script should recall itself with the new path.
I thought that I had an idea of how to it using a for loop with if statements to test the directory for the stick bits and the sub-directories, but I cannot even get the function to list the file that I created with the sticky bit. I know this is way wrong, but this is how i started my script just to test for the sticky bit.
#!/bin/bash
setuid(){
for file in $1; do
if [ -u $file ]; then
ls -l $file
fi
done
}
setuid $1
Like I said, this is terrible and I have a feeling that I do not know what I'm actually doing. I am a super noob, and any help is appreciated.
Thanks for the quick response. I didn't set $1 just in this example, but have tried the directory that I created the file in and I cannot get i to work. You think that I should use a while loop instead?
The value of $1 will be a directory or "." if no argument is specified. You are correct the I haven't got ti the recursion yet. However, if you have any tips on making it recall itself when a directory is encountered and the new directory path included in the argument it would be greatly appreciated.
I know it said not to do this in the rules, but maybe I am not explaining what I need to do very well. Here is the full problem.
Write out a bash script called 'b.sh' that has a function that can be called recursively to scan the directory specified by it's first argument ($1) for any file that is setuid and print out that file in ls -l format. For any directory it encounters the function should call itself with the new computed path. This function should be called initially with the first argument supplied to the script or "." if no argument is supplied to the script.
So let us step back a little for a sec. If you supply something like '.', your for loop will look like:
Code:
for file in .
do
...
done
So this will run the contents of the for loop for exactly 1 iteration using '.' as the only thing to be tested.
Now if we wanted to look at all the items inside the '.' directory, we would need something like:
Code:
for file in $1/*
do
...
done
Now the glob will expand to all items, files and directories, within that top directory.
As for the recursion, firstly you need to remember to test what type of item you are looking at, ie so that once a directory is found you can recall your function.
Another thing to remember, scope of variables will play a part (if you are not careful)
Thank you, grail. That gets me started in the right direction. Its getting kind of late here, so I will have to continue with this in the morning. Any other tips you might think of that can help me along the way would be greatly appreciated. I will post back on here tomorrow if I am still stuck. Thanks!
if [ ! $1 ]; then
FIRST_PARM="."
else
FIRST_PARM="$1"
fi
for FILE in $FIRST_PARM .....etc.....
If you check $1 and it has not been passed, then your script will fail. Where $1 is the first parameter. And $0 is the name of the script. Also bear in mind that some distros like debian default to dash. Even if you set your shell to bash, when you launch a script with sh or ./ it will run under dash. Unless you run it "bash script.sh". It probably wont affect your low level thing, but some bash extras do not function under dash. Like ${VAR:1:1} to parse parts of strings.
@Shadow_7 - The below is invalid information based on the interpreter already having been set inside the script:
Quote:
Even if you set your shell to bash, when you launch a script with sh or ./ it will run under dash. Unless you run it "bash script.sh".
By defining the interpreter at the start of the script, once executed it will use that interpreter (in this case the bash shell) to process the data inside the script.
Also, without a glob, your for loop will also not function as expected.
@Shadow_7 - The below is invalid information based on the interpreter already having been set inside the script:
By defining the interpreter at the start of the script, once executed it will use that interpreter (in this case the bash shell) to process the data inside the script.
Also, without a glob, your for loop will also not function as expected.
It depends on the distro and the day of the week I guess. For me:
would work on CLI, but not in a script. In debian sid if launched with sh or ./ it fails via Bad substitution (as it would in dash), even with the #! /bin/bash as the header. But if launched with bash it executes as expected. If done on the cli in bash it works. If done on the cli in dash (debians default) it fails. For all intents the interpreter line at the top of the script is ignored (in debian). In theory it shouldn't be, but in practice it appears to be.
Well I will have to believe you as I am not familiar with Debian, although it does seem to fly in the face of any other distribution I have used and the whole point of defining an interpreter.
Out of curiosity, what if the interpreter is perl or python, does it ignore these too?
I am not sure why you use export in your example either, is there a reason you cannot simply assign the values?
I mean your example makes sense as it is on the cli, hence subject to whichever shell you are in.
If I add the +x permission and use ./ it uses the interpreter line. Otherwise sh uses dash and bash uses bash, regardless of what the interpreter line says. And ./ wont run at all without the +x permission.
I can use just the var name in script, and I guess it works on the cli for the example without the export. But doesn't work if you're wanting something like LANG set and passed when you chroot using a one liner.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.