Linux - GeneralThis Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then 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 want to CHOWN a bunch of files (few thousand) to a specific owner/group. This is easy, right? Just type this.
chown owner:group *
Within' the directory all the files reside in. Well, the problem is some of the files start with a "-" thus giving the chown command an error when it reaches this file.
Code:
chown: invalid option -- 1
Try `chown --help' for more information.
I then tried to wrap the last bit of the command with quotes.
chown owner:group "*"
This doesn't work either. I even tried using single quotes, then tried getting more specific with the names DM-*, *.uz, etc... all will not work.
How can I get around the issue with the few files that start with a hyphen?
Use double hyphen: One hyphen for specifying an option ("here comes an option, parse it!"), and a second one for the option itself, which too is a hyphen. This option specifies that everything that follows is indeed a filename.
add "--" before the *. doing that means that nothing following the double dash is interpretted as an option, so will work with that filename fine.
Worked excellently. Will also help me with a script problem I've been having as well, since moving some of those file names with dashes at the beginning was disrupting the "mv" command. I take it I can apply the same method here too.
Probably totally suitable here, but the OP doesn't mention wanting to do any subdirectories, so this could be confusing.
Good point and thanks for pointing it out.
BTW the chown man page does not document option "--" to end options, hence my -R suggestion. Similarly its syntax summary (chown [OPTION]... [OWNER][:[GROUP]] FILE...) does not include having options after specifying the owner (so the OP example should have worked). Hmm ... ?
maybe putting putting wildcard on both sides. well it worked over here chown $USER:$GROUP "*-*" check with ls before run that command
That should not have worked because the double quotes should have prevented filename expansion and chown should have been given exactly *-* as file name to operate with. Are you sure it worked?
BTW the chown man page does not document option "--" to end options, hence my -R suggestion. Similarly its syntax summary (chown [OPTION]... [OWNER][:[GROUP]] FILE...) does not include having options after specifying the owner (so the OP example should have worked). Hmm ... ?
For the record, their are no sub directories in the directory. Just a crap load of files.
I wonder if the MV command has the same thing as well. Because I get the same error with similar files if I try to move multiple files using a wild card with the mv command.
It could possibly think that the first source could be that of a option, if the file name begins with a dash. It also does the same if it's within' a director. Example:
Run the command from /home to move files in /home/upload/files/a
mv /home/upload/files/a/-afile.ga /home/backup/
This will return an error exactly as shown in the first post, yet the option is after directories have been declared. Strange.
This will return an error exactly as shown in the first post, yet the option is after directories have been declared. Strange.
I was not able to reproduce that behaviour:
Code:
c:~/d/bin/try$ ls -l -- *file
-rw-r--r-- 1 c users 0 Jan 24 18:39 -a.file
c:~/d/bin/try$ mv ~/d/bin/try/-a.file /tmp
c:~/d/bin/try$ mv --version
mv (GNU coreutils) 7.4
[snip]
Neither ls --help output nor the ls man page describe "--" to terminate options but it works, as shown above.
The ls, mv and chown man pages' syntax summaries all show that options must be given before arguments but simple tests show all three accepting an option after an argument:
Code:
c:~/d/bin/try$ /bin/ls /tmp/*file -l
-rw-r--r-- 1 c users 0 Jan 24 18:39 /tmp/-a.file
c:~/d/bin/try$ chown c /tmp/*file -d
chown: invalid option -- 'd'
Try `chown --help' for more information.
c:~/d/bin/try$ mv /tmp/*file . -v
`/tmp/-a.file' -> `./-a.file'
removed `/tmp/-a.file'
I am surprised; I thought man pages were definitive. IIRC, UNIX (including Solaris and HP-UX) commands did not look for options after the first argument.
AFAIK, it's not bash; bash simply tokenises "words" before presenting them to the named executable and leaves the executable to parse the argument list. Bash' own getopts does not have any support for "--" but can be used to implement it (imperfectly: the error trap for "-" does not work).
EDIT: that's not right; the following code stops processing options on finding "-" whether or not followed by another "-"
Code:
#!/bin/bash
while getopts 'h-' opt
do
case $opt in
h )
echo 'Got option -h'
\exit 0
;;
'-' )
echo 'Got option -'
case "$OPTARG" in
'-' )
break
;;
* )
echo 'invalid option -'
\exit 0
;;
esac
;;
* )
echo "Invalid option '$opt'"
esac
done
echo 'Finished processing options; now processing arguments'
From the X Open Group's The Single UNIX ® Specification, Version 2, Utility Conventions (could not find anything later): "Guideline 10: The argument -- should be accepted as a delimiter indicating the end of options" so it is required for POSIX compliance. All the same, when it is implemented it would be nice to see it mentioned in the man page.
Netsearching did not find anything about options appearing in the arguments.
EDIT:
From the getopt(3) man page (my bolding): "By default, getopt() permutes the contents of argv as it scans, so that eventually all the non-options are at the end. Two other modes are also implemented. If the first character of optstring is '+' or the environment variable POSIXLY_CORRECT is set, then option processing stops as soon as a non-option argument is encountered. If the first character of optstring is '-', then each non-option argv-element is handled as if it were the argument of an option with character code 1. (This is used by programs that were written to expect options and other argv-elements in any order and that care about the ordering of the two.) The special argument "--" forces an end of option-scanning regardless of the scanning mode."
Last edited by catkin; 01-25-2010 at 09:54 AM.
Reason: Removed spurious copy-and-paste
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.