Tag Info

New answers tagged

3

You've got too many shells doing some processing in there. Also, using backticks is a bad idea especially when there's going to be backslashes in them. You should use the $(...) syntax instead. sudo -s starts a shell to run the command, but with sudo trying to escape some of the special characters for the shell. You don't want to use that. ssh runs a shell ...


0

when I'm trying to use this command var1=`sudo -u psoadmin -H -s ssh daill_scp@files.dc1.responsys.net find . -maxdepth 1 -type f -mtime +14 -exec ls -lh \{} \; | awk '{print $5, $9}'|egrep -v '^./upload|^./download|^./archive|^\.'` it is throwing me as find: missing argument to `-exec' You should use this: var1=`sudo -u psoadmin -H -s ssh ...


0

You can also try to skip the \ before the semicolon or double quote it... It must be some problem with the syntax on your machine (not reading the semicolon), these variations work on mine... if there was nothing found, you would get a different message


0

Try on this way: ...-exec ls -lh {} \;... (remove backslash before curly bracket) Double quotes: var1=`sudo -u psoadmin -H -s ssh daill_scp@files.dc1.responsys.net "find . -maxdepth 1 -type f -mtime +14 -exec ls -lh {} \; "| awk '{print $5, $9}'|egrep -v '^./upload|^./download|^./archive|^\.'`


0

When quoting gets too tough consider using bash functions: myfunc() { awk -F '\t' -v OFS='\t' '$1 { if($3 !~ /needle/){print;} ;}' "$1" > "$1".output } export -f myfunc parallel myfunc {} ::: *.txt


2

This looks like a quoting issue. Perhaps the easiest way to debug this is to pass the option --dry-run to parallel: $ parallel --dry-run "awk -F '\t' -v OFS='\t' '$1 { if($3 !~ /needle/){print;} ;}' {} > {}.output" ::: in awk -F '\t' -v OFS='\t' ' { if( ~ /needle/){print;} ;}' in > in.output There you can see that your variables $1 and $3 have ...


-2

Try this: IFS=$(echo -en "\n\b") touch "$yourfile"


0

Try this: $ spam="foo bar" $ touch "$spam" $ ls -l -rw-rw-r-- 1 user user 0 Mar 29 05:14 foo bar


2

In a command substitution delimited with $(…), what's inside the parentheses is parsed in the same way as a toplevel command (except in a few corner cases involving unbalanced closing parentheses). What's inside the parentheses is an ordinary shell snippet, there's no additional backslash expansion being done. The command echo '\\' prints three characters: ...


1

It has more to do with quoting, $ echo '\' \ $ echo '\\' \\ $ echo "\\" \ With single quotes, whatever is there between quotes is echoed. With double quotes, the shell looks inside and does processing.


2

I think it's best understood by the output of echo $(echo '\\') (i.e. a variant without the outer quotes), which results in \\. The point is that there's no literal string interpretation of the backslash(es) when the command substitution entity $(...) is expanded. (This is similar in case you have escape characters stored in strings; there won't be a ...


0

use single quotes since double quotes is doing $ stuff in the first shell


5

You need to escape the quotes in the echo command to see them in the output, but you shouldn't escape them in the actual command: #!/bin/bash echo ./yowsup/yowsup-cli demos --s $1 \"$2\" -c yowsup/config & ./yowsup/yowsup-cli demos --s $1 "$2" -c yowsup/config & The quotes are used in the actual command to prevent splitting of $2 - which contains ...


1

Use find to do all the filename filtering.  Rather than find . -name "*.cpp" | grep "foo" | xargs grep … do find . -name "*.cpp" -name "*foo*" -print0 | xargs -0 grep … If you want to do something slightly more complicated, like find . -name "*.cpp" | egrep "foo|bar" | xargs grep … you can do find . -name "*.cpp" "(" -name "*foo*" -o -name "*bar*" ...


2

If you have to jump through alot of hoops, then the efficiency of xargs is lost anyway. Here is one crude work around: find . -iname "*.cpp" | grep "<pattern>" | while read -r x; do grep exa "$x"; done Every time I run into problems with spaces in file names, the answer is double quotes on a variable.


2

This should work even without GNU tools: #Find all C++ files that match a certain pattern and then search them find . -name "*.cpp" \ | grep "<name regex>" \ | perl -pne 's/\n/\0/' \ | xargs -0 grep "<content regex>" The perl call replaces line breaks with null characters, which will allow xargs -0 to interpret the input on a per-line ...


5

Use something like this perhaps (if gnu grep). grep -r 'content pattern' --include==*.cpp man grep --include=GLOB Search only files whose base name matches GLOB (using wildcard matching as described under --exclude) Also see the options for null delimiters. -Z, --null Output a zero byte (the ASCII NUL character) instead of the character that ...


3

Since you have been using double quotes, any $-variables will be expanded by bash before they reach awk. That's the first problem: { print $1, $3 } will expand to { print , }. Next, the awk syntax you are trying to use is /<regular expression>/ { <action> }: the regular expression is not allowed to contain any unquoted slashes, but $PWD ...


1

how about for filepath in "$1/"*.flac do ffmpeg -i "${file_path}" -f ... where "$1/"*.flac will garantee .flac suffix in the end be sure to quote "${file_path}" basename can be found using bn=$(basename "${file_path}") un flac'ed basename can be found using bnnf=$(basename "${file_path}" .flac) sample A > ls -l Music total 0 -rw-rw-r-- ...


0

For completeness, within "..." you can disable with backslash the characters shell still obeys; they are backslash itself \ doublequote " dollar $ backtick ` and (if shell supports history expansion and it isn't disabled) bang !. But (I agree) the singlequote approach is probably better here.


1

Try single quotes: wget 'http://xxxx/Sankarea - 6 - It`s Because I... Ran Into You (720p-100MB)[Commie][Daylighter].mkv' and if you would have a single quote in the URL itself then split the URL in two strings and insert the single quote with a backslash: '...'\''....' or using double quotes: '...'"'"'....'. Leave no spaces between these strings. $ echo ...


0

The main error here is thinking that the single quotes around 'echo \"a\"' would stop "word splitting" performed by the shell and pass echo "a" as a single argument to sh. In this case, the single quotes are actually treated as "literal" not "syntactical" because they are included within the outer double quotes! The following link helped me the most: ...


2

That cannot work. When your shell performs word splitting, you will have four arguments: sh -c 'echo "a"' To accomplish this, you must use a bash array: cmd=( sh -c 'echo "a"' ) "${cmd[@]}"


6

If you want to search for the regexp that is the concatenation of the arguments with space characters in between, that would be: #! /bin/sh - IFS=' ' # used for "$*" grep -r --color=always -e "$*" . | nolong "$*" joins the positional parameters with the first character (actually byte except with yash) of $IFS. Note (as you seem to be confused by the ...


1

You need to quote the argument when your script is called to show that it is one argument and not two independent arguments. Inside your script you then have to use "$@". grep -r --color=always "$@" . | nolong And the call is (for example)... findstr "hello world" (But note that the grep pattern uses just one argument, so "$1" instead of "$@" would ...


1

try this: Escape all . by replacIng all . to \. str1="$( echo -n $i | sed 's/\./\\\./g' )" repeat same for str2 using $j . then replace as follows sed "s/$str1/$str2/g"


1

You can just use sed to do the fixup for you: printf '%s\n' "$i" "$j" | sed 's/[]\$*&/.^[]/\\&/g;H;$!d x;y|\n|/|;s|.*|s&/g|' | sed -f - /path/to/infile So this s///ubstitution will escape any/all BRE metacharacters in input: s/[]\$*&/.^[]/\\&/g ...by prefixing each with a backslash. The first sed then saves a copy of the first ...


2

You need to escape dot in search pattern: sed -i 's/1\.0/2.0/g' /home/user1/file1.txt


1

I think what you're trying to ask is how to mix and match variables that much be evaluated locally with those that need to be evaluated remotely. One option is to write a script for the actions to be handled remotely, thus encapsulating any reference to local variables so that the local host's quotes can't see them to expand them. Another option for a ...


1

You can see for yourself: [user@bluepc ~]$ echo "$HOSTNAME;" bluepc; [user@bluepc ~]$ echo '$HOSTNAME;' $HOSTNAME; Environment variables within single quotes are treated as strings. In the case of ssh, if you use double quotes: The string is substituted at local server. The command is executed remotely. if you use single quotes: The string is ...


0

No, bash escape character preserves the literal value of the next character that follows, from left to right, so \\* give you pattern \*. This pattern is performed Filename Expansion, with the Pattern Matching rules. So \* is interpret as all files starting with \ and follows by anything. In your case it matched nothing and bash left the pattern \* ...


0

Try... set file* printf %s\ "\\$@" It will prepend a a backslash to the head of the array - so only the first element. You can do the same with the end. You can get get them all split out on \\ backslashes like: printf \\%s file* ...or... set file*; IFS=\\; printf %s\\n "$*"


2

If you don't have a file in the current directory whose name starts with a backslash, this is expected behaviour. Bash expands * to match any existing file names, but: If the pattern does not match any existing filenames or pathnames, the pattern string shall be left unchanged. Because there was no filename starting with \, the pattern was left as-is ...


0

Try this: printf "\\%s" "$(echo *)" Explanation: printf takes a format argument and zero or more arguments that are substituted into the format string \\ in the format has the same meaning as in echo \\ %s means take the next argument and substitute it into the result "$(echo *)"means: execute echo *, and put the result into a single argument to printf; ...


3

The first issue is that $directory contains slashes which are also being used as the delimiter for the substitution operator (s///). Basically, if $directory is /home/je_b, what Perl sees is: perl -i -pe "s/foo//home/jb/ if \$. == 4" file.txt It takes the / of /home as the second / of the s/// operator. The simplest solution is to use a different ...


3

In the following lines, workspace="~/GIT_Workspace/my_project/" filename="~/GIT_Workspace/Back/$timestamp-$branch.tar.gz" ~ is not getting expanded to your home directory because it's inside quotes. It needs to be outside of quotes in order to get expanded. So your script is trying to open a file that begins with a literal ~ character, which of course ...


2

In the example you mention, where the expansion for the alias is single word containing no character that is subject to expansion, it makes no difference how you quote the name _cutf: $ alias cutf="_cutf" $ alias cutf alias cutf='_cutf' $ unalias cutf $ alias cutf='_cutf' $ alias cutf alias cutf='_cutf' $ unalias cutf $ alias cutf=_cutf $ alias cutf alias ...


1

It's just that simple - if there's no variable, the brackets are interchangeable. Shell script, while very useful, is also a very simple language. I (and some others I know) tend to use double quotes by default, just from force of habit - and I have never run into issues.


0

SSH runs a shell command. It concatenates its parameters with spaces in between and runs that command remotely. Thus when you type this in your local shell ssh rundeck@nagios1 sudo su - root -c 'printf "Disable_Notification;web01;App:Tomcat:Log:webapp" >> /opt/nagios/nagios.cmd' this is what is executed in the remote shell: sudo su - root -c printf ...


8

You need to quote the variables and avoid the command substitution: for i in ./*.mkv; do ffmpeg -i "${i}" -vcodec copy -acodec copy "${i}.mp4"; done See When is double-quoting necessary? for a detailed explanation of quoting. While I'm at it, the above produces files with a .mkv.mp4 extension; to fix that: for i in ./*.mkv; do ffmpeg -i "${i}" -vcodec ...


0

Refer to this answer, combined with some other sudo and ssh flags to allocate a Pseudo TTY. ssh -t rundeck@nagios1 "sudo -u root sh -c 'printf \"Disable_Notification;web01;App:Tomcat:Log:webapp\" >> /opt/nagios/nagios.cmd'"


2

To search for a parenthesis character, pass backslash+parenthesis to ack. Both backslash and parentheses are special in the shell, so you need to quote them when you're entering them in a shell script or on the command line. The simplest form of quoting is with single quotes: this tells the shell to pass everything through literally except single quotes ...


2

The problem was that since the su statement was in double quotes, the variables were all expanded before the su command was called, which means $var becomes "cat" but $i becomes "" since it was not defined. Bash doesn't know that it was supposed to be an iterator variable, it just expands it to a NULL string. The answer is to escape that "$" like so: ...


1

The special parameter ${array[@]} in double quotes causes word splitting if the array has more than one member: $ for word in "for i in ${arr[@]} ; do" ; do echo "$word" ; done for i in a b c ; do If your modules' names don't contain spaces, you can have more luck using the * subscript: $ for word in "for i in ${arr[*]} ; do" ; do echo "$word" ; done for ...


0

i don't know the exact error you get, but here it works using escaped parenthesis ("\(") $ cat > test.c <<EOF int main() { return 0; } EOF $ ack '\(' test.c int main() { $


2

You can use the wildcard * for the name that you don't know. Let's say you set FILE=../"$1"/*.txt Wildcard expansion only happens outside of quotes. $FILE variable still has the asterisk in it. So, [ -f "$FILE" ] is equivalent to [ -f "../test/*.txt" ] which wants a literal asterisk in the filename, but [ -f $FILE ] is equivalent to [ -f ...


1

Variables are interpreted in a here doc (<<...), so you need to escape the ones you don't want evaluated yet. su - db2prd<<EOF PARMDATE=1111111 echo parmdate echo \$PARMDATE EOF Or better, quote the delimiter (here EOF) to tell your shell not to perform expansions inside the here-document: su - db2prd<<'EOF' PARMDATE=1111111 echo ...


0

You can use: sed "s/'"'/&\\&&/g s/.*/'"'&'"'/ ' <<IN $arbitrary_value IN To safely shell quote a value line per line. Shell depending, you might also have the option to do: printf %q\\n "$arbitrary_value" Though I usually prefer to do: a=$(alias "a=$arbitrary_value" a); a=${a#*=} A more manual approach could look like: ...


13

The tutorial is wrong. POSIX says: A single-quote cannot occur within single-quotes. Here's some alternatives: echo $'It\'s Shell Programming' # ksh, bash, and zsh only, does not expand variables echo "It's Shell Programming" # all shells, expands variables echo 'It'\''s Shell Programming' # all shells, single quote is outside the quotes echo ...



Top 50 recent answers are included