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.
If i know my time format and parse according to that, its not a problem. If i am going to run my script in various linux machines with different time format, then i can get rid of the timestamp and it will work as well... ok, so one aspect solved.
You gave that script to someone else to use and you weren't even aware of the potential problems. Later you solved a potential problem (that you had not been aware of) that you never would have encountered if you had not used ls in the first place.
Quote:
What's the next unsafe scenario, if you may?
Ok, one more just for fun: spaces in file names:
Code:
touch a.txt
touch "c b.txt"
for f in $(ls *.txt) ; do echo "File is $f" ; done
for f in * ; do echo "File is $f" ; done
If you don't want to take my advice, that's fine.
Continue using ls.
Cheers,
Evo2.
PS. If you really want to discuss using ls in this fashion login to #linux at irc.freenode.net when GNU\Colossus is online: he'll have plenty to say on the topic.
Last edited by evo2; 12-14-2009 at 11:28 PM.
Reason: PS.
You gave that script to someone else to use and you weren't even aware of the potential problems. Later you solved a potential problem (that you had not been aware of) that you never would have encountered if you had not used ls in the first place.
i didn't say i will give my script to someone else to use. Even if i did, the problem is already taken care of.
Quote:
Ok, one more just for fun: spaces in file names:
Code:
touch a.txt
touch "c b.txt"
for f in $(ls *.txt) ; do echo "File is $f" ; done
for f in * ; do echo "File is $f" ; done
i always advocate that if you want to parse file names, don't use for loop with ls like that, since its useless use of ls. Use shell expansion. If you really want to do that, change IFS
Code:
IFS=$'\n';for i in $(ls *); do echo "$i"; done
or use a while read loop.
however, this example doesn't apply here in this problem. I am asking, what other "unsafe" scenario for this case only. I am parsing ls -l for the owner and filename like OP wanted , and i have already taken care of that. What else?
File names containing non-printable characters including backspace, linend etc. More fully explained in Greg's WIKI in Why you shouldn't parse the output of ls.
EDIT: similar discussion beginning with this LQ post.
Last edited by catkin; 12-15-2009 at 01:38 AM.
Reason: Formatting
yes, thank you. That's one point to keep in mind.
To get back to topic, I only want to know what's "unsafe" for OP's problem. If i may reiterate, he just wants to get .bash_history (which no newlines or special characters in file name) and parsing ls to get the owner ( and not filename ) is alright and not "unsafe". If i do want to parse file names as well and i know it possible that my filenames can contain other chars or newlines, I won't recommend parsing ls either.
I only want to know what's "unsafe" for OP's problem.
As you point out, .bash_history does not contain any unprintable characters and I do not know of any versions of ls that do not ordinarily put the user name in space-separated field 3 so your code is safe in all known circumstances -- except ls could be (and often is) an alias
Code:
c:/tmp$ alias ls='ls -Di'
c:/tmp$ ls -l
total 8
212610 srwxr-xr-x 1 c users 0 Dec 15 11:37 OSL_PIPE_1000_SingleOfficeIPC_f24b151f1666ce0a2d65526a3964194
210604 drwx------ 2 c users 4096 Dec 15 11:35 ssh-CciYjZ3847
212654 drwxr-xr-x 2 c users 4096 Dec 15 11:53 sv5pd.tmp
//DIRED// 58 119 168 182 231 240
//DIRED-OPTIONS// --quoting-style=literal
c:/tmp$ \ls -l
total 8
srwxr-xr-x 1 c users 0 Dec 15 11:37 OSL_PIPE_1000_SingleOfficeIPC_f24b151f1666ce0a2d65526a3964194
drwx------ 2 c users 4096 Dec 15 11:35 ssh-CciYjZ3847
drwxr-xr-x 2 c users 4096 Dec 15 11:53 sv5pd.tmp
Thanks to everyone who replied. This was my final result and it works perfectly and now I can use it for class today.
Code:
#!/bin/bash
echo "Please note that if you do not have sudo priviliges, you only copy your own .bash_history."
echo "Please enter your user name: "
read admin
mkdir -pv /home/$admin/history
for f in /home/*/.bash_history ; do
owner=$(stat --print %U $f)
cp -p $f /home/$admin/history/${owner}.history && chown $admin /home/$admin/history/*
done
The other thing I'm a bit confused about is that the user running the script, enters their username... the shell can get that from the $USER variable.. and that user will own the cp of the file anyway.
The other thing I'm a bit confused about is that the user running the script, enters their username... the shell can get that from the $USER variable.. and that user will own the cp of the file anyway.
Cheers,
Evo2.
I'll try that. I used $USER at first, but when running sudo it took user root as the $USER. And for some reason running without sudo at school lets me see permission denied for every user, but running with sudo only copied 1 user, administrator, my teacher, and root.
EDIT:
And I still can't copy everyone. I get 2 people I'm actually supposed to copy, then administrator and root.
EDIT..again..
Sorry for the confusion. It did work, my teacher just told me he accidentally copied the same .bash_history to everyones folder.
Hey, if it helps anyone, I was bored in class and modified it further. It now combines all the history files into one large file, with "username"'s history above their history section and I added the lastlog command to the end and saved results to a file called login_info
Code:
#!/bin/bash
echo "Please note that if you do not have sudo priviliges, you only copy
your own .bash_history."
echo "Please enter your user name: "
read admin
mkdir -pv /home/$admin/history
rm -Rf /home/$admin/history/*
for f in /home/*/.bash_history ; do
owner=$(stat --print %U $f)
cp -p $f /home/$admin/history/${owner}.history
sed -i "1i-----------------------------------\n"${owner}"'s history\n-----------------------------------\n" /home/$admin/history/${owner}.history
chown $admin /home/$admin/history/*
done
lastlog >> /home/$admin/history/login_info
cat /home/$admin/history/*.history >> /home/$admin/history/history
rm /home/$admin/history/*.history
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.