I was reading the man of find on the -exec command {} switch section, it states that the {} should be quoted to protect from interpretation by shells. I'm trying to reproduce such a behaviour locally without any success and wondering in what context does that interpretation apply. Here is what i am doing trying to get that interpretation to work: echo &quot;Hi&quot; &gt; f1 touch -- \$\(ls\ \-la\) -n find ./ -type f -exec cat {} +  Just basically trying to get either a switch or a command to be interpreted as it's parsing the malicious file names, but it doesn't get interpreted as suggested in the man. What am i missing ? Alternatively is there a way to exploit such a line code with cat as a command and not any other ?
50121
The man page for GNU find states:    -exec command ;     [...] The  string `{}'  is  replaced  by the current      file name being processed everywhere it occurs in the      arguments to the command, not just in arguments where      it is alone, as in some  versions  of  find.     Both  of  these  constructions might need to be escaped      (with a `\') or quoted to protect them from expansion      by the shell.     That's from the man to find (GNU findutils) 4.4.2.   Now I tested this with bash and dash, and both don't need to have the {} being masked. Here is a simple test:  find /etc -name "hosts" -exec md5sum {} \;    Is there a shell, for which I really need to mask the braces? Note, that it doesn't depend upon whether the file found contains a blank (invoked from bash):   find ~ -maxdepth 1 -type d -name "U*" -exec ls -d {} \;  /home/stefan/Ubuntu One   This changes if the found file is passed to a subshell:  find ~ -maxdepth 3 -type d -name "U*" -exec bash -c 'ls -d {}' \;  ls: cannot access /home/stefan/Ubuntu: No such file or directory ls: cannot access One: No such file or directory   which can be solved by:  find ~ -maxdepth 3 -type d -name "U*" -exec bash -c 'ls -d "$0"' {} \;   in contrast to:   find ~ -maxdepth 3 -type d -name "U*" -exec bash -c 'ls -d "{}"' \;  /home/stefan/Ubuntu One   but that's not what the man page is talking about, is it? So which shell treats {} in a different way?
42354
From the :   -exec command ;     There are unavoidable security problems     surrounding use of the -exec action; you should use the     -execdir option instead.  -execdir command {} +     Like -exec, but the specified command is run from the     subdirectory containing the matched file, which is not     normally the directory in which you started find.  This a much     more secure method for invoking commands, as it avoids race     conditions during resolution of the paths to the matched     files.    What does this mean? Why are there race conditions with running it from the starting directory? And how are these security risks?
96183
I use set -e to .  All work OK unless I use command with &amp;&amp;:  $ cat script set -e cd not_existing_dir &amp;&amp; echo 123 echo "I'm running! =P" $ $ ./script ./script: line 2: cd: not_existing_dir: No such file or directory I'm running! =P $   compared with:  $ cat script set -e cd not_existing_dir echo "I'm running! =P" $ $ ./script ./script: line 2: cd: not_existing_dir: No such file or directory $   The first example still echoes I'm running!, but the second one doesn't. Why do they behave differently?  UPD. Similar question:
12595
I'm using find with the -exec option in console, on FreeBSD (for example, find . -exec sha1 {} \;).   How do I correctly place (and if needed, escape) redirect and other execution control symbols that could syntactically apply to either of the exec command or the find command, such as > >> | and &amp;, where I might want the symbol to apply to the find or the exec commands on different occasions?  On the same theme, what is the syntax if I want to use tee to view the output of the -exec commands on the console (to watch progress) and also appended to a file (for later use)?   (I know shells vary but hopefully the most used shells such as sh/csh are quite similar?)  Update:  In part, I want to learn if nested find -exec can be done without scripting, as a simple command. Here is the use-case that prompted the questio :   outer find: find all subdirs matching DIR_MATCH_TEXT in DIR1  inner find: for each matching subdir found in the outer loop (call it DIR2), execute the commandfind DIR2 -name "FILE_MATCH_TEXT" -exec sha1 {} \; &gt;&gt; DIR1/DIR2_hashes.txt   The aim being to create a set of files, one for each matching subdir, containing the output of some find -exec action on that subdir.  By this I mean that, if /backups contains /jan2017 and /feb2017, the result will be two files at /backups/jan2017_hashes.txt and /backups/feb2017_hashes.txt, with jan2017_hashes.txt containing the output from sha1 for (say) all .pdf files in /backups/jan2017, and feb2017_hashes.txt containing the output from sha1 for all .pdf files in /backups/feb2017.  From replies so far I gather the outer find would have to use a shell call as the argument to -exec?
30221
Suppose I want a bash command to do something extra.  As a simple example, imagine I just want it to echo "123" before running.  One simply way to do this would be to alias the command.  Since we still need the original, we can just refer to it by its exact path, which we can find using which.  For example:  $ which rm /bin/rm $ echo "alias rm='echo 123 &amp;&amp; /bin/rm'" &gt;&gt; .bashrc   This was easy because I was able to look up the path to rm using which.  However, I am trying to do this with exit, and which doesn't seem to know anything about it.  $ which exit $ echo $? 1   The command did not output a path, and in fact it returned a non-zero exit code, which which does when a command is not in $PATH.  I thought maybe it's a function, but apparently that's not the case either:  $ typeset -F | grep exit $ echo $? 1   So the exit command is not defined anywhere as a function or as a command in $PATH, and yet, when I type exit, it closes the terminal.  So it clearly is defined somewhere but I can't figure out where.  Where is it defined, and how can I call to it explicitly?
21956
I am trying to understand named pipes in the context of this particular example.  I type &lt;(ls -l) in my terminal and get the output as, bash: /dev/fd/63: Permission denied.  If I type cat &lt;(ls -l), I could see the directory contents. If I replace the cat with echo, I think I get the terminal name (or is it?).  echo &lt;(ls -l) gives the output as /dev/fd/63.  Also, this example output is unclear to me.  ls -l &lt;(echo "Whatever") lr-x------ 1 root root 64 Sep 17 13:18 /dev/fd/63 -&gt; pipe:[48078752]   However, if I give,ls -l &lt;() it lists me the directory contents.   What is happening in case of the named pipe?
91318
In the sequence of five commands below, all depend on single-quotes to hand off possible variable substitution to the called bash shell rather than the calling shell. The calling user is xx, but the called shell will be run as user yy. The first command substitutes $HOME with the calling shell's value because the called shell is not a login shell. The second command substitutes the value of $HOME loaded by a login shell, so it is the value belonging to user yy. The third command does not rely on a $HOME value and creates a file in the guessed home directory of user yy.  Why does the fourth command fail? The intention is that it writes the same file, but relying on the $HOME variable belonging to user yy to ensure it actually does end up in her home directory. I don't understand why a login shell breaks the behaviour of a here-doc command passed in as a static single-quoted string. The failure of the fifth command verifies that this problem is not about variable substitution.  xx@host ~ $ sudo -u yy bash -c 'echo HOME=$HOME' HOME=/home/xx xx@host ~ $ sudo -iu yy bash -c 'echo HOME=$HOME' HOME=/home/yy xx@host ~ $ sudo -u yy bash -c 'cat &gt; /home/yy/test.sh &lt;&lt; "EOF" &gt; script-content &gt; EOF &gt; ' xx@host ~ $ sudo -iu yy bash -c 'cat &gt; $HOME/test.sh &lt;&lt; "EOF" &gt; script-content &gt; EOF &gt; ' bash: warning: here-document at line 0 delimited by end-of-file (wanted `EOFscript-contentEOF') xx@host ~ $ sudo -iu yy bash -c 'cat &gt; /home/yy/test.sh &lt;&lt; "EOF" &gt; script-content &gt; EOF &gt; ' bash: warning: here-document at line 0 delimited by end-of-file (wanted `EOFscript-contentEOF')   These commands were issued on a Linux Mint 18.3 Cinnamon 64-bit system, which is based on Ubuntu 16.04 (Xenial Xerus).  Update: The here-doc aspect is just clouding the issue. Here's a simplification of the problem:  $ sudo bash -c 'echo 1 &gt; echo 2' 1 2 $ sudo -i bash -c 'echo 1 &gt; echo 2' 1echo 2   Why does the first of those two commands preserve the linebreak and the second does not? sudo is common to both commands, yet seems to be escaping/filtering/interpolating differently depending on nothing but the "-i" option.
58712
I often end up issuing complex commands over ssh; these commands involve piping to awk or perl one-lines, and as a result contain single quotes and $'s.  I have neither been able to figure out a hard and fast rule to do the quoting properly, nor found a good reference for it.  For instance, consider the following:  # what I'd run locally: CMD='pgrep -fl java | grep -i datanode | awk '{print $1}' # this works with ssh $host "$CMD": CMD='pgrep -fl java | grep -i datanode | awk '"'"'{print $1}'"'"   (Note the extra quotes in the awk statement.)  But how do I get this to work with, e.g. ssh $host "sudo su user -c '$CMD'"?  Is there a general recipe for managing quotes in such scenarios?..
11493
From      Storing the regular expression in a shell variable is often a useful way to avoid problems with quoting characters that are special to the   shell. It is sometimes difficult to specify a regular expression   literally without using quotes, or to keep track of the quoting used   by regular expressions while paying attention to the shell’s quote   removal. Using a shell variable to store the pattern decreases these   problems. For example, the following are equivalent:  pattern='[[:space:]]*(a)?b' [[ $line =~ $pattern ]]       and  [[ $line =~ [[:space:]]*(a)?b ]]       If you want to match a character that’s special to the regular   expression grammar, it has to be quoted to remove its special meaning.   This means that in the pattern xxx.txt, the . matches any   character in the string (its usual regular expression meaning), but in   the pattern "xxx.txt" it can only match a literal .. Shell   programmers should take special care with backslashes, since   back-slashes are used both by the shell and regular expressions to   remove the special meaning from the following character. The following   two sets of commands are not equivalent:  pattern='\.'  [[ . =~ $pattern ]] [[ . =~ \. ]]  [[ . =~ "$pattern" ]] [[ . =~ '\.' ]]       The first two matches will succeed, but the second two will not,   because in the second two the backslash will be part of the pattern to   be matched. In the first two examples, the backslash removes the   special meaning from ., so the literal . matches. If the string in   the first examples were anything other than ., say a, the pattern   would not match, because the quoted . in the pattern loses its   special meaning of matching any single character.   How is storing the regular expression in a shell variable  a useful way to avoid problems with quoting characters that are special to the shell?  The given examples don't seem to explain that. In the given examples, the regex literals in one method and the values of the shell variable pattern in the other method are the same.   Thanks.
111951
The idea would be to use it as... a pipe in a command. For instance: say there's some kind of long path which has to be retyped again and again, followed by a pipe and a second program, i.e.  "directory1/directory2/direcotry3/file.dat | less -I "   I'd like that part to be stored in a variable, so it could be used like this:  r="directory1/directory2/direcotry3 \| less -I -p " $ cat path1/path2/$r &lt;searchterm&gt;   Instead, I get  cat: invalid option -- I Try `cat --help' for more information.   ... meaning the pipe clearly didn't work.
25581
I'm reading shell tutorial today from   In which it mentions:     If a single quote appears within a string to be output, you should not put the whole string within single quotes instead you whould preceed that using a backslash () as follows:   echo 'It\'s Shell Programming'   I tried this on my centos server, it doesn't work, a &gt; prompts out to hint me type more.  I was wondering, since two single quotes transform every special characters into normal characters,  which include escape symbol \, but exclude itself, the ', how should I represent a single single quote 'in a single-quoted phrase?
64994
file contains just 1 line:  aaa   when I run "cat file" it mixes to username  user /dir : cat file aaauser /dir :   What could be the problem ?  Extra Info:  perhaps this is not properly set in bashrc ? ?  PS1='\u \W : '   UPDATE:  shouldnt there be a solution other than including a newline to the file ?  Why would there be no care for the elements that can distort the command line prompt ? ( by not having a new line )
64001
The find command seems to differ from other Unix commands.  Why is there the empty curly brackets and a backward flash at the end of the following command?  find * -perm 777 -exec chmod 770 {} \;   I found one reason for the curly brackets but not for the backward flash.   The curly brackets are apparently for the path     Same as -exec, except that ``{}'' is   replaced with as many pathnames as   possible for each invocation of   utility
123931
It's high time to solve this conundrum that's been bothering me for years...  I've been meeting this from time to time and thought this is the way to go:  $(comm "$(arg)")   And thought my view was strongly supported by experience. But I'm not so sure anymore.  can't make up its mind too. It's both:  "$(dirname $0)"/stop.bash            ^-- SC2086: Double quote to prevent globbing and word splitting.   And:  $(dirname "$0")/stop.bash ^-- SC2046: Quote this to prevent word splitting.   What's the logic behind?   (It's Shellcheck version 0.4.4, btw.)
31776
In sh (not Bash), how would we abort execution of command when the prompt is in &gt; mode?  For example, when entering a string with quotes only at the beginning, it makes the prompt look like &gt;, without the ability to quit it normally, unless hitting Ctrl + D. Example:  root@MyPC:~# echo "hello &gt; I am &gt; (How do I exit of this mode?)   In case that I don't know which character delimits the string (" or ' or simply escaping a newline/spaces with backslash), is there a way to let Bash know that I want to abort the execution of the current command?
47349
Sometimes when I simply type a valid command like 'find ...', or anything really, I get back the following, which is completely unexpected and confusing (... is command name I type): sh: $'\302\211...': command not found  There is some corruption going on I think. I don't use color in my prompt, I am using the Bash shell in POSIX mode as sh (chsh to /bin/sh and so on - $SHELL is sh). What is going on and why does this keep happening? Anything I can debug? I think this is more of an xterm issue than sh, or at least a combination of the two. Files, for context: My /etc/profile, as distributed with Arch Linux x86-64: # /etc/profile  #Set our umask umask 022  # Set our default path PATH=&quot;/usr/local/sbin:/usr/local/bin:/usr/bin&quot; export PATH  # Load profiles from /etc/profile.d if test -d /etc/profile.d/; then         for profile in /etc/profile.d/*.sh; do                 test -r &quot;$profile&quot; &amp;&amp; . &quot;$profile&quot;         done         unset profile fi  # Source global bash config if test &quot;$PS1&quot; &amp;&amp; test &quot;$BASH&quot; &amp;&amp; test -r /etc/bash.bashrc; then         . /etc/bash.bashrc fi  # Termcap is outdated, old, and crusty, kill it. unset TERMCAP  # Man is much better than us at figuring this out unset MANPATH  My /etc/shrc follows below. It's something I created as a way to have sh parse some file on startup, for a non-login shell; it is achieved using ENV variable set in /etc/environment with the line ENV=/etc/shrc: PS1='\u@\H \w \$ ' alias ls='ls -F --color' alias grep='grep -i --color' [ -f ~/.shrc ] &amp;&amp; . ~/.shrc  My ~/.profile, I am launching X when logging in through first virtual tty: [[ -z $DISPLAY &amp;&amp; $XDG_VTNR -eq 1 ]] &amp;&amp; exec xinit -- -dpi 111  My ~/.xinitc, as you can see I am using the system as a Virtual Box guest: xrdb -merge ~/.Xresources  VBoxClient-all  awesome &amp;  exec xterm  And finally, my ~/.Xresources, no fancy stuff here I guess: *faceName: Inconsolata *faceSize: 10 xterm*VT100*translations: #override &lt;Btn1Up&gt;: select-end(PRIMARY, CLIPBOARD, CUT_BUFFER0)  xterm*colorBDMode: true xterm*colorBD: #ff8000 xterm*cursorColor: S_red  Since ~/.profile references among other things /etc/bash.bashrc, here is its content: # # /etc/bash.bashrc #  # If not running interactively, don't do anything [[ $- != *i* ]] &amp;&amp; return  PS1='[\u@\h \W]\$ ' PS2='&gt; ' PS3='&gt; ' PS4='+ '  case ${TERM} in   xterm*|rxvt*|Eterm|aterm|kterm|gnome*)     PROMPT_COMMAND=${PROMPT_COMMAND:+$PROMPT_COMMAND; }'printf &quot;\033]0;%s@%s:%s\007&quot; &quot;${USER}&quot; &quot;${HOSTNAME%%.*}&quot; &quot;${PWD/#$HOME/~}&quot;'                                                              ;;   screen)     PROMPT_COMMAND=${PROMPT_COMMAND:+$PROMPT_COMMAND; }'printf &quot;\033_%s@%s:%s\033\\&quot; &quot;${USER}&quot; &quot;${HOSTNAME%%.*}&quot; &quot;${PWD/#$HOME/~}&quot;'     ;; esac  [ -r /usr/share/bash-completion/bash_completion   ] &amp;&amp; . /usr/share/bash-completion/bash_completion  I have no idea what that case statement does, by the way, it does look a bit suspicious though, but then again, who am I to know.
20132
I was just trying to list all directories and files under current directory and also write if they are file or directory with the following command:  find -exec echo `echo {} : ;if [ -f {} ]; then echo file; else echo directory;fi` \;   I know it is a silly command, I can use other things like -type f or -type d, but I want to learn why that piece of code did not work as I expected. It just prints directory to all of them. For example while output of find is:  . ./dir ./dir/file   output of my code is :  . : directory ./dir : directory ./dir/file : directory   And output of   echo `echo dir/file : ;if [ -f dir/file ]; then echo file; else echo directory;fi`   is  dir/file : file   I am working on Ubuntu 14.10 and using find (GNU findutils) 4.4.2