What the hell is the "+" meta character used for in linux?

C

CrazedNerd

Guest
Anyone want to explain? I'm not seeing this anywhere on the first page of google or duck-duck-go.
 


Crazednerd wrote:
Code:
the "+" meta character
As a metacharacter "+" has it's own features in different contexts, just as the common metacharacters "*" and "?" do. Whereas * and ? have a meaning largely separate from their conventional orthographic expressions when they occur in shells and programming languages used in linux, the + sign can tend to be related more to its original meaning which is related to addition and adding in some form or other. For example, you could check out some of its uses described in the manpages of find and bash.
"in the man pages" it's often used to add or subtract ( - ) an option, but in these contexts:

Code:
find ~ -type f -name 'foo*' -exec ls -l '{}' +

find playground -name 'file-A' | tar czf playground.tgz -T -

There's something else going on...i have my .bashrc page configured so that i can't overwrite files, but if i execute "set +C" i can turn it back to default overwriting of text files. Unfortunately, that doesn't clue me in to whats going on in those commands. Plus, the minus sign is normally what's used to add an option, so it's not straghtfoward at all...
 
i guess one should never say things like "what the heck" in conjunction with "if you want", because then people will try to answer when they don't really understand what's going on either...
 
The use of + and - in the example you have given: set +C, is that the + has turned on clobber since the -C option means noclobber. That explains why your files can be overwritten.

On the more general point in relation to + and -, I draw your attention to this quote which may be explanatory for you in relation to the particularity of meanings for + and - :
"The basic commands that relate to options are "set -o <option-name>" and "set+o <option-name>. You can change more than one option with the one set command by preceding each option-name with -o or +o. The use of plus (+) and minus (-) signs is counterintuitive: the - turns the named option on, whilst the + turns it off. The reason for this incongruity is that the dash (-) is the conventional UNIX way for specifying options to a command while the use of + is an afterthought."
Newham C & Rosenblatt B. 1998. Learning The Bash Shell (Second Edition). O'Reilly, p. 63.

As for the usage of + and - in the find commands you provided, the multiple meanings depend on context and are clearly described in one of the better man pages which do a much better job at explication than I can.
 
The use of + and - in the example you have given: set +C, is that the + has turned on clobber since the -C option means noclobber. That explains why your files can be overwritten.

On the more general point in relation to + and -, I draw your attention to this quote which may be explanatory for you in relation to the particularity of meanings for + and - :

Newham C & Rosenblatt B. 1998. Learning The Bash Shell (Second Edition). O'Reilly, p. 63.

As for the usage of + and - in the find commands you provided, the multiple meanings depend on context and are clearly described in one of the better man pages which do a much better job at explication than I can.
You would think it means turning off/on sequences of options, yet that doesnt explain what going on in that command. I wonder if the + and - are shell builtins because in that case theyd have
--help/info pages associated with them.
 
Crazednerd wrote:
You would think it means turning off/on sequences of options, yet that doesnt explain what going on in that command. I wonder if the + and - are shell builtins because in that case theyd have
--help/info pages associated with them.
Although it is the case that undocumented options exist in various applications and programs in linux, this particular case is not one of those. I refer you to the bash manpage. It's massive, but the information relevant to the issue is there.

Shell builtins are commands, such as "alias", "break", "pushd", "popd" etc. The characters "+" and "-" are metacharacters which have their various defined functions.

What you "would think" exists, sounds like wishful thinking for something to actually exist, as opposed to what does in fact exist in the form of information that is accessible in various documents. The quality of documentation varies with some of it requiring a greater level of pre-existing knowledge on the part of the reader which can be frustrating at times, and some is poorly written in the sense that it lacks clarity, but often explanations from a variety of "non-official" sources online or in publications can help.
 
Crazednerd wrote:

Although it is the case that undocumented options exist in various applications and programs in linux, this particular case is not one of those. I refer you to the bash manpage. It's massive, but the information relevant to the issue is there.

Shell builtins are commands, such as "alias", "break", "pushd", "popd" etc. The characters "+" and "-" are metacharacters which have their various defined functions.

What you "would think" exists, sounds like wishful thinking for something to actually exist, as opposed to what does in fact exist in the form of information that is accessible in various documents. The quality of documentation varies with some of it requiring a greater level of pre-existing knowledge on the part of the reader which can be frustrating at times, and some is poorly written in the sense that it lacks clarity, but often explanations from a variety of "non-official" sources online or in publications can help.
It would probably make sense for you to a particular man page, because so far you've been talking about man pages as they have information im looking for but you haven't mentioned a particular man page, nor do you seem to understand what + and - mean to the shell. Im not trying to be hostile, im just pointing out the fact that the specific is missing. One could, however, put every man page in vim, nano, or less and search "+" and "-" until one found how they are used in the absense of options and mathematics.
 
Crazednerd wrote:
you haven't mentioned a particular man page
The bash manpage was mentioned, and the find manpage was inferred as one of the better written ones.
nor do you seem to understand what + and - mean to the shell.
It's not a matter of what I understand, rather it's a matter of what + and - mean in the shell, and it's clear to me that there are a variety of meanings depending on the command and the context with the relevant information being in manpages associated with the commands, as well as other documents and publications.

There is no secret to the queries you have. Linux and the bash shell are open in multiple respects. Sometimes discovering just what you want takes time and effort and can be frustrating. Other times information is easily come by and helps whatever project is in play. Your point about "the specific is missing" is not at all clear to me. If it was and I had an answer I would gladly provide it. At a guess, and it's only a guess, it seems that you are seeking some core meaning (a "specific") to the meanings of + and - in the shell, but I don't see how such a core exists, nor can I imagine what it might be. As I've mentioned, + and - have various meanings depending on context.
 
Crazednerd wrote:

The bash manpage was mentioned, and the find manpage was inferred as one of the better written ones.

It's not a matter of what I understand, rather it's a matter of what + and - mean in the shell, and it's clear to me that there are a variety of meanings depending on the command and the context with the relevant information being in manpages associated with the commands, as well as other documents and publications.

There is no secret to the queries you have. Linux and the bash shell are open in multiple respects. Sometimes discovering just what you want takes time and effort and can be frustrating. Other times information is easily come by and helps whatever project is in play. Your point about "the specific is missing" is not at all clear to me. If it was and I had an answer I would gladly provide it. At a guess, and it's only a guess, it seems that you are seeking some core meaning (a "specific") to the meanings of + and - in the shell, but I don't see how such a core exists, nor can I imagine what it might be. As I've mentioned, + and - have various meanings depending on context.

I've processed the bash manpage with grep, and this is all there is about either of the signs themselves:

Code:
-      
-      Expands to the current option flags as specified upon invocation, by the set builtin command, or those          set by the shell itself (such as the -i option).

and then there is discussion of addition and subtraction, so there is nothing in the bash page in particular that we haven't already discussed here...however, there are still those command examples i gave above, which are described like this:

Code:
By changing the trailing semicolon character to a plus sign, we activate
the capability of find to combine the results of the search into an argument
list for a single execution of the desired command. Returning to our example,
this will execute ls each time a matching file is found:

find ~ -type f -name 'foo*' -exec ls -l '{}' +

the book is referring to this, the changing of the ; to the +:

Code:
find ~ -type f -name 'foo*' -exec ls -l '{}' ';'

Then, the second example i gave:

Code:
find playground -name 'file-A' | tar czf playground.tgz -T -

before the pipe (|), find is finding every file named 'file-A' in the working directory hierarchy, and then that is being put into the tar command...an archive command. The archive command is being used to (c) create an archive (z) compress with gunzip (f) specify filename, with the -T option after the name of the archive (described with "the default N is 1" in the manpages, the fallowed by the "-" entirely by itself. Maybe i'm just dumb, i don't know, but none of those examples makes any sense.
 
CrazedNerd wrote:
I've processed the bash manpage with grep, and this is all there is about either of the signs themselves:
Code:
-
- Expands to the current option flags as specified upon invocation, by the set builtin

I am unsure of what you were looking at. The manpage for bash reveals numerous instances and meanings for +. Here are some with heading sections in which they appear:
OPTIONS
[-+]O [shopt_option]
shopt_option is one of the shell options accepted by the shopt builtin (see SHELL BUILTIN COMMANDS below). If shopt_option is present, -O sets the value of that option; +O unsets it.

SHELL GRAMMAR
The return value of a simple command is its exit status, or 128+n if the command is terminated by signal n.

PARAMETERS
When += is applied to a variable for which the integer attribute has been set, value is evaluated as an arithmetic expression and added to the variable's current value, which is also evaluated.

BASH_SOURCE
An array variable whose members are the source filenames where the corresponding shell function names in the FUNCNAME array variable are defined. The shell function ${FUNCNAME[$i]} is defined in the file ${BASH_SOURCE[$i]} and called from ${BASH_SOURCE[$i+1]}.

TIME_FORMAT

%P The CPU percentage, computed as (%U + %S) / %R.

Brace Expansion

If strict compatibility with sh is desired, start bash with the +B option or disable brace expansion with the +B option to the set command

Tilde Expansion
If the tilde-prefix is a `~+', the value of the shell variable PWD replaces the tilde-prefix.
There are more. We may be corresponding at cross-purposes here.
 
Last edited:
Hello again CrazedNerd.

In relation to the find commands that you asked about, I refer you to a text here:
It's downloadable and the whole book is a treasure trove of useful command line ideas. In particular Chapter 9 deals with the find command. It may not answer all your queries in the way you have asked them, but it will be informative and in conjunction with the man page should be able to shed light on your commands.
 
Hello again CrazedNerd.

In relation to the find commands that you asked about, I refer you to a text here:
It's downloadable and the whole book is a treasure trove of useful command line ideas. In particular Chapter 9 deals with the find command. It may not answer all your queries in the way you have asked them, but it will be informative and in conjunction with the man page should be able to shed light on your commands.
Thanks osprey, its seems like a good book or was back in 2002. My main interest is just in using those metas without options, i tested the find command above and notes a difference in how the command "behaved" when it was replaced with the semi colon, however i still dont get it. Its alright since coding is inherently a puzzle, yet it bothers when something simple still doesn't make any sense after a while.
 
Hello again CrazedNerd.

In relation to the find commands that you asked about, I refer you to a text here:
It's downloadable and the whole book is a treasure trove of useful command line ideas. In particular Chapter 9 deals with the find command. It may not answer all your queries in the way you have asked them, but it will be informative and in conjunction with the man page should be able to shed light on your commands.
I like how these tools are specifically Unix instead of "linux", and "whereis" is still located on my Ubuntu jammy jellyfish.
 
"in the man pages" it's often used to add or subtract ( - ) an option, but in these contexts:

Code:
find ~ -type f -name 'foo*' -exec ls -l '{}' +

find playground -name 'file-A' | tar czf playground.tgz -T -

There's something else going on...i have my .bashrc page configured so that i can't overwrite files, but if i execute "set +C" i can turn it back to default overwriting of text files. Unfortunately, that doesn't clue me in to whats going on in those commands. Plus, the minus sign is normally what's used to add an option, so it's not straghtfoward at all...
In those two specific cases:
Bash:
find ~ -type f -name 'foo*' -exec ls -l '{}' +
The + is being used to terminate the command instead of \;.

What the + will do there is append the rest of the results from find to the argument list of the ls command used in the -exec.

So the ls command will only be ran once, with a potentially large list of files. And it looks like the single quotes around the curly braces that act as a placeholder for the results are probably to avoid problems with spaces or other special characters in the file names.

Whereas if you used \; at the end of the command instead of +, then ls would be called each time a result was found.

However, you need to be careful when using find's + operator.
Especially with commands like ls.

If you are expecting a large number of results, the argument list for ls could potentially end up exceeding the maximum argument list length - which is a fixed value in bash.
If you do this, the ls command will fail because the argument list is too long.

But if you're only expecting a more limited number of results, then using + is ok to use and will be faster than using \;, because the ls command (or whatever other command you might be using) will only be ran once, instead of once per result.

For the second case:
Bash:
find playground -name 'file-A' | tar czf playground.tgz -T -
For some commands a - at the end of the command indicates that it should read from stdin.
There are a number of commands that can do this - other than tar. I can't think of any offhand, but I know there are several.

In this highly specific case, the -T option to tar tells it to read the list of files to add to the archive from a file.
Usually after the -T option, you would provide a file-name.
But in this case - the - tells it that everything else should be read via stdin - so effectively the file to read is stdin.

So looking at the entire command - the stdout of the previous find command is being piped to the stdin of the tar command.
And tar has been set up to read from stdin, thus allowing the output from find to be read by tar as if it was reading file-paths/names from a file.

And if nothing was being redirected to stdin, then the tar command would wait for the user to manually enter a list of files/directories via the keyboard. And it will keep reading lines from stdin until the user presses ctrl+D.

Try for yourself:
1. Open a terminal.
2. Run ls to see what files/folders you have in your local directory. Optionally move to a different directory and list its contents.

3. Run the following tar command:
Bash:
tar -cvzf somefile.tar.gz -T -
Now the shell will wait for you to enter paths to files/directories.
4. Carefully enter some valid file/directory names.
5. Press ctrl+D when you're finished.
6. Now run ls somefile.tar.gz and you should see the new tar.gz file listed.
7. Run tar --list -f somefile.tar.gz and you should see that the .tar.gz contains the files you specified.
8. Now feel free to remove the .tar.gz with rm!

Anyway, getting back on topic - those are the specific effects of those operators, in those two highly specific situations/contexts.

When it comes to using + and - they are often contextual. It's not always the same for every single command.

Typically, most commands use - as a prefix for all parameters/switches/options.

However, sometimes + or - can be used as a prefix, to turn specific options on/off. Again, this varies from command to command, or program to program. Some support it, others do not. I can't think of any examples offhand, but I have seen a fair few programs over the years that accept parameters like that.

And then you other specialized cases, like find's + operator, which allows further results to be appended to the commands used for its -exec or -execdir options. This is a rarity. I'm not sure of any other commands that do anything like this.

And like tar's use of - at the end of the line, to specify that the remainder of the command should be read from stdin. Again, there are several other commands that also accept a - at the end of the line, in order to specify that the rest of the command will come from stdin. And if nothing is being piped/redirected to stdin, the command will end up waiting for the user to manually enter some information and press ctrl+D when they are done.

I hope this helps somewhat?!
 
Last edited:
In those two specific cases:
Bash:
find ~ -type f -name 'foo*' -exec ls -l '{}' +
The + is being used to terminate the command instead of \;.

What the + will do there is append the rest of the results from find to the argument list of the ls command used in the -exec.

So the ls command will only be ran once, with a potentially large list of files. And it looks like the single quotes around the curly braces that act as a placeholder for the results are probably to avoid problems with spaces or other special characters in the file names.

Whereas if you used \; at the end of the command instead of +, then ls would be called each time a result was found.

However, you need to be careful when using find's + operator.
Especially with commands like ls.

If you are expecting a large number of results, the argument list for ls could potentially end up exceeding the maximum argument list length - which is a fixed value in bash.
If you do this, the ls command will fail because the argument list is too long.

But if you're only expecting a more limited number of results, then using + is ok to use and will be faster than using \;, because the ls command (or whatever other command you might be using) will only be ran once, instead of once per result.

For the second case:
Bash:
find playground -name 'file-A' | tar czf playground.tgz -T -
For some commands a - at the end of the command indicates that it should read from stdin.
There are a number of commands that can do this - other than tar. I can't think of any offhand, but I know there are several.

In this highly specific case, the -T option to tar tells it to read the list of files to add to the archive from a file.
Usually after the -T option, you would provide a file-name.
But in this case - the - tells it that everything else should be read via stdin - so effectively the file to read is stdin.

So looking at the entire command - the stdout of the previous find command is being piped to the stdin of the tar command.
And tar has been set up to read from stdin, thus allowing the output from find to be read by tar as if it was reading file-paths/names from a file.

And if nothing was being redirected to stdin, then the tar command would wait for the user to manually enter a list of files/directories via the keyboard. And it will keep reading lines from stdin until the user presses ctrl+D.

Try for yourself:
1. Open a terminal.
2. Run ls to see what files/folders you have in your local directory. Optionally move to a different directory and list its contents.

3. Run the following tar command:
Bash:
tar -cvzf somefile.tar.gz -T -
Now the shell will wait for you to enter paths to files/directories.
4. Carefully enter some valid file/directory names.
5. Press ctrl+D when you're finished.
6. Now run ls somefile.tar.gz and you should see the new tar.gz file listed.
7. Run tar --list -f somefile.tar.gz and you should see that the .tar.gz contains the files you specified.
8. Now feel free to remove the .tar.gz with rm!

Anyway, getting back on topic - those are the specific effects of those operators, in those two highly specific situations/contexts.

When it comes to using + and - they are often contextual. It's not always the same for every single command.

Typically, most commands use - as a prefix for all parameters/switches/options.

However, sometimes + or - can be used as a prefix, to turn specific options on/off. Again, this varies from command to command, or program to program. Some support it, others do not. I can't think of any examples offhand, but I have seen a fair few programs over the years that accept parameters like that.

And then you other specialized cases, like find's + operator, which allows further results to be appended to the commands used for its -exec or -execdir options. This is a rarity. I'm not sure of any other commands that do anything like this.

And like tar's use of - at the end of the line, to specify that the remainder of the command should be read from stdin. Again, there are several other commands that also accept a - at the end of the line, in order to specify that the rest of the command will come from stdin. And if nothing is being piped/redirected to stdin, the command will end up waiting for the user to manually enter some information and press ctrl+D when they are done.

I hope this helps somewhat?!
Yes, that is helpful, it's something i can mull over when i have the time...find is a really annoying/complicated command in my opinion...like its general behavior (of looking through child directories, "file system hierarchies" in a addition to working directories) it also has a hierarchy of options...of course like rsync, having tons of options can make it better than simpler commands in very specific situations.
 
What the + will do there is append the rest of the results from find to the argument list of the ls command used in the -exec.

That definitely makes sense to me to me overall...but what would happen if you put "-" at the end of that find command? My feeble mind finds xargs to be a much more friendly command in it's basic form than using "-exec" with find, yet one of the things that makes bash such a ridiculous programming language is that each command binary is its own part of it, and it would be hard to fully understand any of them if you didn't make it yourself...lot's of commands only have around 10 arguments, which is something i can put up with, but commands like find and rsync are so crazy and specialized.
 
Oh and @JasKinasis how are you putting the codeblocks around single words like "find", "ls", etc...
By putting inline code tags (icode) around words in my posts.
E.g.
List files using the [icode]ls[/icode] command.

Would yield:
List files using the ls command.

And if you want to know how I’ve shown the [icode][/icode] tags in this post, without them rendering as as actual icode blocks - I’ve simply wrapped the icode tags in plain tags, so they’re treated as plain text, rather than as tags! Ha ha!
Another neat little trick I’ve picked up whilst using BBS code.

I don’t use the insert buttons in the post composer’s toolbar to add code, or icode blocks, I manually enter BBS tags as I write my posts.
 
Last edited:


Latest posts

Top