Tag Info

Hot answers tagged

39

This is not a bug in the cp command. When you enter cp *.pdf, cp never sees the actual wildcards because the wildcards are expanded by bash, not by cp. How will cp know that you have entered only one argument? This is a side effect of bash wildcards and cannot be called a bug.


30

You can use the process substitution operator <() of bash (or zsh): 4s-import <(zcat huge.gz) This operator will create a temporary fifo /dev/fd/NN and replace <(.) with the string /dev/fd/NN. 4s-import now can open /dev/fd/NN and read from that fifo, while bash will run zcat huge.gz, which sends its output to /dev/fd/NN.


19

You seem to understand what is happening perfectly well. In your example, *pdf indeed expands to file1.pdf file2.pdf this_is_a_folder.pdf. I don't see what's confusing you. cp is doing exactly what it should, you are telling it to copy file1.pdf and file2.pdf into this_is_a_folder.pdf and that is exactly what it is doing. There is no bug, it is working as ...


18

You're close: rm /some/path/{file1,file2} or even rm /some/path/file{1,2} Related, and supported by other shells, is a pattern like rm /some/path/file[12] The first two are expanded to two explicit file name arguments; the third is a pattern against which all files in /some/path are matched.


15

Many programs have a - as standard input. If yours does, use that as it's "builtin". You can also try using /dev/stdin or /dev/fd/0 as a file. A third option is to use mkfifo to create a fifo special file. In one shell you pipe in your data (eg. gunzip > your_fifo_file), while in the other you call your program with the fifo as the file.


11

ps does not hide the password. Applications like mysql overwrite arguments list that they got. Please note, that there is a small time frame (possible extendible by high system load), where the arguments are visible to other applications until they are overwritten. Hiding the process to other users could help. In general it is much better to pass passwords ...


11

You can simply use xargs xsel | xargs -n1 echo mycommand -n1 means one arg for mycommand, but it's just dry run, it will show what going to be run, to run it remove echo For constant Argument xsel | xargs -I {} -n1 echo mycommand "constantArgument" {}


9

You're in zsh, not bash. In zsh, repeat (inspired from csh repeat) is a construct used to repeat commands. repeat 10 echo foo Would echo foo 10 times. If you want to call your repeat, you'd need to quote it so that it's not taken as the repeat reserved word. $ echo $ZSH_VERSION 5.0.2 $ 'repeat'() echo "$*" $ type -a repeat repeat is a reserved word ...


8

They're completely different. Command-line arguments are passed to the program in an array and it can do what it wants with them; stdin is an input stream the program has to request data from. Programs that process files often choose to support both, but they have to do so manually -- they check if a filename was passed as a command-line argument, and if not ...


7

I just can give you an overall answer: Command line options are often parsed using the library function "getopt". Originally it only accepted aguments consisting of a - followd by a symbol. This effectively limits the amount of options you have, more or less -A to -Z, -a to -z and -0 to -9. You can imagine that you will not use an option without at least a ...


7

Since you're working in bash, use an array. excludes=() excludes+=('--exclude=/path/*') … tar -czf backup.tgz "${excludes[@]}" If you have an optional entry in some variable, add it in a conditional. if [[ -n $exclude_or_empty ]]; then excludes+=("$exclude_or_empty"); fi


7

That depends what kinds of arguments your application expects. If it processes files, it's traditional to read from standard input and write to standard output if no arguments are specified (example: cat, tee, …). If the application has an interactive mode, start it if no arguments are specified (example: sh, ed). If the application expects an object to work ...


7

It's not a bug, it's a side-effect doing of wildcard expansion once in the shell rather than implementing it in every program. Now, there are some much stranger ways you can trip yourself up with this, especially by creating files whose names start with "-". For example (in an empty directory): $ touch -- --version $ ls --version $ rm * rm (coreutils) ...


6

This can be done using command substitution, like so: mvn -Dvar_name="$(cat /path/to/file)" # POSIX mvn -Dvar_name="$(</path/to/file)" # bash This has a notable caveat, though, namely that all trailing newlines are stripped. If that doesn't matter, though, then that should work. If you really just want to read one line, you could use read instead, ...


6

tar -czf backup.tgz "$exclude1" "$exclude2" ${exclude3+"$exclude3"} 2>&1 ${exclude3+"$exclude3"} expands to nothing, if $exclude3 is unset, and to "$exclude3", if it is set. (and similarly for the other variables that are potentially unset.) Note that there is a difference between an unset variable and a variable that is set to the empty string, ...


6

Many of the compressors take an an environment variable to accept options that cannot be passed on the command line. In your case GZIP_OPT=-9 sort --compress-program=/bin/gzip The same is true for xz with XZ_OPT and bzip2 with BZIP2


5

Alternatively you can take advantage of the Readline library in Bash. This is a bit of a workaround, but relatively easy to type. ls /some/path/ rm ESC.file1 ESC.file2 (Assuming your meta prefix is the ESC key.) The extra ls in the first command puts the path in the history as the last argument of the previous command, ESC. (or as the manual states M-. ...


5

There's a special syntax for this: for i do echo "$i" done More generally, the list of parameters of the current script or function is available through the special variable $@. for i in "$@"; do echo "$i" done Note that you need the double quotes around $@, otherwise the parameters undergo wildcard expansion and field splitting. "$@" is magic: ...


5

Your question is closely related of how the shell you are using parses user input on the command line. If the first word on the command line is a program, located in a special folder (mostly defined by PATH) and no more special characters are given (depends of the shell you are using), all subsequent words separated by spaces or tabs are passed to the ...


5

As the other answers already pointed out, bash expands the wildcard and then passes what it sees to cp. In your case, cp sees file1.pdf file2.pdf this_is_a_folder.pdf. Now let's prevent it. Don't use wildcards. Use the -t, --target-directory switch and specify the target. Always declare at the very end a destination after using a wildcard. cp *.pdf ...


5

The first non-option argument to sh becomes $0. When sh is invoked on a script, that's the path to the script. When you run sh -c SOMECOMMAND, the name isn't used by the shell, it's only placed into $0. Unlike most commands, -- is treated as an ordinary argument, not as a special-purpose marker. So it's really -- that's used as $0 and not the next argument. ...


5

Why would you want to use echo? Use printf: printf -- '-n\n' Or: printf '%s\n' -n With echo: echo -n Will output -n<LF> in a Unix conformant echo. bash, dash, GNU or zsh echo can do it with: echo -en '-n\n' Or: echo -e '\055n' Zsh echo can do it with: echo - -n bash (but not zsh): echo -n -; echo n Interestingly, it is impossible ...


5

I'd make heavier use of I/O redirection: #!/bin/bash [[ $1 ]] && [[ ! -f $1 ]] && echo "file $1 dne" && exit 1 [[ $1 ]] && exec 3<$1 || exec 3<&0 [[ $2 ]] && exec 4>$2 || exec 4>&1 fgrep -v "stuff" <&3 >&4 Explanation [[ $1 ]] && [[ ! -f $1 ]] && echo "file $1 dne" ...


5

You're looking for this: ls -C | awk '{ print $2 }' However, assuming you're going to try and use this filename later, don't do this, as it will break on filenames containing whitespace. Instead, put the files into an array, and get the second one, which avoids having to do any parsing at all: files=(*) printf '%s\n' "${files[1]}" The order in which ...


5

You're assigning files as a scalar variable instead of an array variable. In files=$HOME/print/*.pdf You're assigning some string like /home/highsciguy/print/*.pdf to the $files scalar (aka string) variable. Use: files=(~/print/*.pdf) or files=("$HOME"/print/*.pdf) instead. The shell will expand that globbing pattern into a list of file paths, ...


5

Answers Definitely not a bug. The parameter which defines the maximum size for one argument is MAX_ARG_STRLEN. There is no documentation for this parameter other than the comments in binfmts.h: /* * These are the maximum length and maximum number of strings passed to the * execve() system call. MAX_ARG_STRLEN is essentially random but serves to * ...


4

For command substitution, you need to use $() or backticks ``. It is also important that you quote the substitution, or it will expand into multiple arguments if the file contains more than one word. Here are some examples: mvn -Dvar_name="$(< /path/to/file)" # bash mvn -Dvar_name="$(cat /path/to/file)" # POSIX


4

Use "$@": $ bar() { echo "$1:$2"; } $ foo() { bar "$@"; } $ foo "This is" a test This is:a "$@" and "$*" have special meanings: "$@" expands to multiple words without performing expansions for the words (like "$1" "$2" ...). "$*" joins positional parameters with the first character in IFS (or space if IFS is unset or nothing if IFS is empty).


4

A simple solution is to use Bash's support for process substitution, like this: myCommand <(grep "xyz" somefile) This will connect the output of the grep command to a file descriptor and then pass /dev/fd/NNN (where NNN is the fd number) to your command as the input file (for example, your command might actually get run as myCommand /dev/fd/63). This ...


4

The thing is, options (or switches or flags, whatever you like to call them) count as arguments too. In fact, anything you supply after the command name itself makes up the command's arguments (except for constructs used by the shell like redirection, for instance). Your program/script receives everything together as arguments and needs to separate the ...



Only top voted, non community-wiki answers of a minimum length are eligible