LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   a question about touch command. (https://www.linuxquestions.org/questions/linux-software-2/a-question-about-touch-command-4175442949/)

windbadboy 12-26-2012 12:13 AM

a question about touch command.
 
我想用touch命令在系统里的每个分区建一个文件,检查有没有分区所属的磁盘有无只读情况发生。
I want to create a file on every partition by touch command.
if my linux has 5 partitions like /home1-/home5,each partition represents one physical disk.
when I typed "touch /home[1-5]/1" on my linux,the result:
[root@cu tmp]# touch /home[1-5]/1
touch: cannot touch `/home[1-5]/1': No such file or directory



when I typed ls /home[1-5],It works well.how to get the result I want with one command?

colucix 12-26-2012 02:40 AM

Quote:

Originally Posted by windbadboy (Post 4856843)
when I typed ls /home[1-5],It works well.how to get the result I want with one command?

The expression
Code:

[1-5]
is an interval which is correctly interpreted by the ls command. Nothing to do with shell expansion, instead. If working in bash, you can try extended brace expansion as in
Code:

touch /home{1..5}/file

rknichols 12-26-2012 09:37 AM

Quote:

Originally Posted by colucix (Post 4856895)
The expression
Code:

[1-5]
is an interval which is correctly interpreted by the ls command. Nothing to do with shell expansion, instead.

I find it hard to believe that you don't know better than that. It has everything to do with shell expansion and what the shell does when nothing matches the glob pattern. The ls command does not perform glob expansion.

colucix 12-26-2012 11:56 AM

Quote:

Originally Posted by rknichols (Post 4857094)
I find it hard to believe that you don't know better than that. It has everything to do with shell expansion. and what the shell does when nothing matches the glob pattern. The ls command does not perform glob expansion.

To me an interval like [1-5] has nothing to do (again) with shell expansion, if you agree that shell expansions are those listed here. Instead, it is a range of alphanumeric characters, which falls into the category of patterns. This is the reason why the command mentioned in the OP
Code:

touch /home[1-5]/1
fails, since the shell does not perform any expansion here (even if the directories exist). On the contrary a real expansion does exactly what it is supposed to do:
Code:

touch /home{1..5}/1
The difference is very subtle and we could discuss for hours (what I'd rather avoid). Anyway, something to deepen into, for the sake of clarity.

David the H. 12-26-2012 03:17 PM

I'd say you're both partially right. Or perhaps it's better to say you're both right in respects, but looking at it from different directions.

Something like [1-5] is read by the shell as a globbing pattern to match. When the shell parses the command line (of a simple command), it first looks in the current working directory (or another if the glob is prefixed by an existing path), and if anything matches that pattern, the pattern gets expanded into a list of those matching filenames as arguments. This is then passed to the command.

If nothing matches, then the results depend on the shell settings, but the default is usually to pass the unexpanded string directly as an argument.

In other words, the globbing pattern itself is not file expansion syntax, as it can also be used elsewhere for other purposes (e.g. case statements) but the shell does do file expansion using globs in one of its parsing steps (the last step, by the way).


rknichols is also correct in that the receiving command usually doesn't do any pattern matching of its own (unless its specifically designed to do so, and it manages to get an unexpanded pattern as an argument). The ls command, for one, only attempts to list out the list of pathnames it gets from the shell (or the $PWD if nothing is given), and would simply issue an error if it happened to get an unexpanded, unmatching, string.

For touch, however, if you use a pattern that matches existing files, then it receives that expanded list from the shell, and will update their mtimes (or whatever it's set to do). If it receives a non-matching pattern, it will simply create a new file with that name, just as it would with any other text string.

That's why, in commands like touch you don't use globbing, but brace expansion. The shell always takes brace expansion patterns and expands them to the full list of possible combinations. It doesn't try to match them to anything, so the command you use always gets all the combinations as individual arguments.

windbadboy 12-26-2012 11:34 PM

it works,thanks a lot,friendly men.

rknichols 12-27-2012 12:05 AM

Quote:

Originally Posted by colucix (Post 4857183)
To me an interval like [1-5] has nothing to do (again) with shell expansion, if you agree that shell expansions are those listed here. Instead, it is a range of alphanumeric characters, which falls into the category of patterns.

That is one of the types of shell expansion. In the very reference you cited, it is called "File name expansion" (section 3.4.9, at the bottom of the page).

colucix 12-27-2012 02:40 AM

Quote:

Originally Posted by rknichols (Post 4857480)
That is one of the types of shell expansion. In the very reference you cited, it is called "File name expansion" (section 3.4.9, at the bottom of the page).

True. I stand corrected!

colucix 12-27-2012 02:48 AM

Quote:

Originally Posted by David the H. (Post 4857287)
When the shell parses the command line (of a simple command), it first looks in the current working directory (or another if the glob is prefixed by an existing path), and if anything matches that pattern, the pattern gets expanded into a list of those matching filenames as arguments.

Thank you David for the deep insight. What puzzles me now is why this doesn't work even if the directories exist
Code:

touch /etc/home[1-5]/1
Maybe because the files still don't exist? TIA.

rknichols 12-27-2012 10:29 AM

Quote:

Originally Posted by colucix (Post 4857540)
What puzzles me now is why this doesn't work even if the directories exist
Code:

touch /etc/home[1-5]/1
Maybe because the files still don't exist? TIA.

The match is for the entire path, not just some of the components. That glob will expand to the full paths of any files named "1" in those 5 directories. Since there are (for the OP's case) no such files, the glob fails and the argument is passed literally to the touch command.


All times are GMT -5. The time now is 09:45 PM.