Tag Info

New answers tagged

0

The first problem is that you have a space after the =: TEMP= grep -o [1-9][0-9]\.[0-9] /tmp/temp.txt That's wrong and breaks your script. The next issue is that you're assigning the commands themselves, as strings, to the variables and not their output: $ foo=date $ echo $foo date To run the command and save its output to a variable, you need to use ...


0

First off, that isn't how you pipe something to grep. Also, it is generally considered better form to separate commands from the conditional and just check return codes. Something like the following works perfectly: command=`ls -l` for file in "$command" do echo "$file" | grep 'o' if [ $? -eq 0 ]; then echo "$file" fi done


0

Assuming vcgencmd measure_temp will create a single fixed point number, this command may do what you want: temp=$( vcgencmd measure_temp | grep -o '[1-9]*\.[0-9]' ) date "+%Y-%m-%d %H:%M;${temp}" >> /home/pi/temp_hist.csv


0

Instead of building a string and appending to it, just create the string directly: ➜ ~ DATE="1234" ➜ ~ TEMP="15" ➜ ~ STR="$DATE;$TEMP" ➜ ~ echo $STR 1234;15


3

I like Cyrus's answer, but this syntax also works: #!/usr/bin/env bash fail_color=$'\033[31;1m' color_end=$'\033[0m' function="foo" line_number="42" printf "%sError - Function: %s, Line: %d%s\n" "$fail_color" "$function" "$line_number" "$color_end" And ShellCheck says "It all looks good!". :)


6

fail_color="\033[31;1m" color_end="\033[0m" function="foo" line_number="42" printf "%bError - Function: %s, Line: %d%b\n" "$fail_color" "$function" "$line_number" "$color_end" Output: Error - Function: foo, Line: 42 Tested with Ubuntu 11.04 (bash 4.2.8(1)-release), Ubuntu 14.04.1 LTS (bash 4.3.11(1)-release), RHEL 5.1 (bash 3.1.17(1)-release), RHEL ...


-1

The variable "$fail_color" contains one too many, or one too few backslashes before the 033, try changing it or removing the "" to have it debackslashified. \033 is supposed to be the ESC character (ASCII 27 decimal, 033 octal).


0

If you use bash you can do here-doc $ su - user -s/bin/bash -c <<EOF export X=1 echo $X EOF That way you can execute many commands and keep the state inside a script. The same with sudo sudo -u user <<EOF your script here EOF


1

I have come across the same problem, and my simple solution was to use a variable: E=! curl -v "http://example.org/${E}287s87asdjh2/somepath/someresource" Here the simplicity is that (1) It is portable across shells and commands (2) Does not require knowing escape syntax and ASCII codes.


2

An external linting tool like ShellCheck can detect problems and may have better messages and locations than bash itself. For a program that is mostly echo statements with a "${MY_ARRAY[1]" in the middle, ShellCheck tells you that it couldn't parse the quoted string. It even pins the problem down to the $ character and hints that the parameter expansion was ...


1

awk -v argsec=$((5*60*60)) ' BEGIN{ nowsec=systime() } { logsec=mktime(gensub(/[-:]/," ","g",$1" "$2)); if(nowsec-logsec<=argsec) print; }' logfile Your could put the conversion of 5 hours to seconds in awk's BEGIN block, but it seems more flexitple to have it in an arg variable.


0

You probably should use a batch tool for batch operations. Doing so will usually entail reading/writing all records in a single stream rather than, for example, invoking a separate cp process for each file copied. There is already a cpio answer written here, which, given only the options already provided you is likely what I would choose. However, the cpio ...


2

A low-tech approach is tr -cd "'\n" < run_me.sh | awk 'length%2==1 {print NR, $0}' The tr deletes all characters except for single quotes and newlines, and the awk identifies the lines that have an odd numbers of characters (i.e., non-matching quotes).  Check them out individually; note that valid strings like "That's not a bug!" will be flagged.  If ...


0

To get the login lines from a logfile that have an hour greater than 05:00:00 in column 2 try: awk '$2+0>=5' logfile


0

You're using Bash-like syntax and operators ($(command), ${...//}), but running it by sh, which on Android is not Bash by default.


8

$file | grep -o executes the command specified by the value of file and pipes its output to grep. But that's clearly not what you wanted. If you want to list files that contain o You meant the value of file to be an input file for grep, not a command to execute. So you need an input redirection, not a pipe. if grep 'o' <"$file" grep reads from ...


1

You should not rely on ls output at all. ls is meant to show human friendly output and not to be used within scripts. See the following example; for f in ./* do if [[ $f = *o* ]]; then printf '%s\n' "$f" fi done


4

You're trying to execute $file. Instead, you must echo it: # ... if echo "$file" | grep 'o' ; # ... Note that the grep will already print the filename, so you should silence it (e.g. grep -q 'o' or grep 'o' >/dev/null). You're also passing -l to ls, which you don't want to do. ls -l prints the file name and attributes, and you'll be matching against ...


1

There's nothing wrong with using a temporary variable: variables are made to store data to be used several times. In this case, you can combine the two grep/sed calls into a single call to GNU grep, sed or awk. It's easy with sed: pass the -n option to output only explicitly printed lines, and print the lines on which a substitution is made. echo "$( ...


4

Easiest way? Use an editor with syntax coloring that's aware of the shell you're using, and inspect visually. When you get a big swathe of string color, you know you left out a quote. Just about any decent programming editor has syntax coloring. Syntax coloring sometimes gets it wrong, but that's usually a sign that your program is too complex and humans ...


1

Bash's programmable completion works by parsing the command line and figuring out what is being completed: Some contexts are treated specially, e.g. the first word in a command is completed as a command name, what follows a $ is completed as a variable name, etc. Outside of these contexts, bash attempts to complete the argument of a command, and the ...


1

I think maybe this issue is very the same as yours, you also can check this out: Create sub-directories and organize files by date I write this new script based on that issue's first answer: for x in *; do d=$(date -r "$x" +%Y) mkdir -p "/your/new/directory/$d" mv -- "$x" "/your/new/directory/$d/" done write this script to a file named copy.sh in ...


4

If you have newer files on the old disk that you want to ignore I would go about it like this Create a temporary marker file with a modified-by date that separates files I want from those I don't Copy files older than the marker file to the new location Here are sample commands for this, which assume you want to maintain any directory hierarchy from the ...


4

Do not use ls. It's not recommended to use in such cases. Moreover using grep to filter according to date is not a good idea. You filename might itself contain 2012 string, even though it was not modified in 2012. Use find command and pipe its output. find . -newermt 20120101 -not -newermt 20130101 -print0 | xargs -0 cp -t /your/target/directory Here, ...


-1

The correct syntax is if ! $bool; then [statements]; fi. Example: bool=false if ! $bool; then echo "This is correct!" fi if [ ! $bool ]; then echo "This is wrong!" fi Output: This is correct!


1

For the record, with zsh, there's the ${^array} operator that turns on brace-like expansion on the elements of the array. So: $ a=(one two three) $ b=('foo '${^a}' bar') $ printf '<%s>\n' $b <foo one bar> <foo two bar> <foo three bar> Search and replace also works: $ printf '<%s>\n' ${a//(#m)*/foo $MATCH bar} <foo one ...


0

With zsh: files=(/var/abc/*.csv(N.)) n=0 while (($#files)) { cat $files[1,1000] > file$((++n)).csv && rm -f $files[1,1000] || break files[1,1000]=() }


1

Your command looks almost fine. Just add a cat and >> to actually append the content: for i in /var/abc/*.csv; do cat "$i" >> file1.csv && rm -rf "$i";done I don't quite understand the counting part. You could do something like this: let count=0 for i in /var/abc/*.csv; do cat "$i" >> file1.csv && rm -rf "$i" let ...


2

p='* "foo ' s=' bar $USER' CATEGORIES=(one two three four) CATEGORIES=("${CATEGORIES[@]/#/$p}") CATEGORIES=("${CATEGORIES[@]/%/$s}") paste <(printf '[%s]\n' "${!CATEGORIES[@]}") \ <(printf '%s\n' "${CATEGORIES[@]}") Output: [0] * "foo one bar $USER [1] * "foo two bar $USER [2] * "foo three bar $USER [3] * "foo four bar $USER ...


1

Here's a one liner of the iw command that have the same output as you. iw dev wlp1s0 link | grep 'SSID:\|signal' | awk '{printf "%s ", $2$3}' My output: ZyXEL-AP-2,4GHz -46dBm


0

Something like that ? iw dev wlp1s0 link | grep -E '^\s*(SSID|signal):\s' | sed -r 's/^\s*(SSID|signal):\s//' | awk '{printf $0}' grep will accept (SSID|signal): so it will match both SSID: and signal:. -E is optional, but if you don't use it, think about escaping special meaning character. Here, it would be \(SSID\|signal\): The same regex can be used ...


0

You could use awk: echo $( iw dev wlp1s0 | awk '/(SSID|signal): /{$1 = ""; print;}' )


4

You don't need to loop, you can tell cat to read all the files: cat /var/abc/*.csv > file1.csv && rm /var/abc/*.csv as long as there aren't too many files (but the limit is huge). Using && between the two commands ensures the files are only deleted if they were successfully "copied". There are a couple of caveats though: you mustn't ...


3

Depending on what your ultimate aim is, you could use printf: $ a=(1 2 3) $ printf "foo %s bar\n" "${a[@]}" foo 1 bar foo 2 bar foo 3 bar printf re-uses the format string until all the arguments are used up, so it provides an easy way to apply some formatting to a set of strings.


0

As far as I know, compgen does not have an option to do case-insensitive filtering of the list of options you give it. There is a readline variable which you can set to cause filename completion to be case-insensitive: bind "set completion-ignore-case on" but that doesn't affect the behaviour of compgen, so it probably won't apply to programmable ...


2

You don't need test command when using case, and don't need case when using test: case $1 in ("") echo "something" ;; esac and: [[ -z $1 ]] && echo "something" or using old test [...] for portability: [ -z "$1" ] && echo "something"


1

According the manual (man timeout): Synopsis timeout [OPTION] NUMBER[SUFFIX] COMMAND [ARG]... [...] If the command times out, then exit with status 124. Otherwise, exit with the status of COMMAND Combine this with the knowledge that the exit status or return value is stored in the variable, $?, and we have... timeout 5 ...


3

If timeout times out, it exits with status 124; you can check this to determine whether the script timed out or not.


0

This works for me: STRINGTEST="Some Text 1 Some Text 2 Some Text 3" readarray -t lines < <(echo "$STRINGTEST") echo "${lines[0]}" And it also works for blank lines: STRINGTEST=" Some Text 1 Some Text 2 Some Text 3" readarray -t lines < <(echo "$STRINGTEST") echo "${lines[0]}"


0

A directory, like a file, has an inode associated with it: 307 % mkdir A B C 308 % ls -i 11997708 A 11997709 B 11997710 C An inode is a data structure that contains information about the directory or file. Every directory and file has one. Think of it as an address (an index number really). If I am in A, inode number 11997708 and in another shell (or ...


3

That code works for me with all versions of bash I tried between 2.05b and 4.3. More likely you tried to run that script with a different shell that doesn't support the $'...' form of quoting. That $'...' syntax is not standard sh syntax (yet) and only supported (as of 2015-05-22 and AFAIK) by ksh93 (where it originated), zsh, bash, recent versions of mksh ...


1

Maybe there is other way to archive what you want to do, but this works #!/bin/bash STRINGTEST=" Onlygetthefirstline butnotthesecond orthethird " STRINGTEST=(${STRINGTEST[@]}) echo "${STRINGTEST[0]}"


0

In order to simplify the problem and since your are getting the variable sitename, why don't you read a username variable? With that you'd make sure that the script execution is not dependent on the environmental variables made available the way the script is executed.


0

If, for some reason, $USER is not set, you can use the id command to obtain the identity of the real user. So the first time you use the $USER variable, you can use the shell expansion to supply a default value. Change the chown line in your script to: sudo chown ${USER:=$(/usr/bin/id -run)}:$USER /var/www/$sitename If USER is empty or unset when this ...


1

Closest you'll get is with ps aux. This will show you the number of virtual pages allocated to a program. Whether these pages are actually used, you won't know unless you profile every running process. These numbers should be good enough for finding a leak, though


1

I stole this from drupal.org, but you could do something like this: while [ $# -gt 0 ]; do case "$1" in --p_out=*) p_out="${1#*=}" ;; --arg_1=*) arg_1="${1#*=}" ;; *) printf "***************************\n" printf "* Error: Invalid argument.*\n" printf "***************************\n" exit 1 esac ...


0

For login simulation (without going through "sudo -i"), you have to use "su" command. Checking the man page for parameter '-': -, -l, --login Starts the shell as login shell with an environment similar to a real login: o clears all environment variables except for TERM o initializes the environment variables ...


1

Using \$HOSTNAME is the correct way to escape the variable in this case. However, that variable often contains the hostname (non-fqdn), or may not be populated. You should rather use the command hostname -f to get your server FQDN. I don't know how will look like your final script, but connecting to server1 then check if this server is server1 may be some ...


0

Isn't there some way to protect spaces in backtick (or $(...)) expansion? No, there isn't. Why is that? Bash has no way of knowing what should be protected and what shouldn't. There are no arrays in the unix file/pipe. It's just a byte stream. The command inside the `` or $() outputs a stream, which bash swallows and treats as a single string. As ...


0

Try something like wget -qO- http://www.google.com/ | tr " " \\n | fgrep src= | tr \" \\n | fgrep -v src= which will, however, output URLs as they are written in the file - which may be relative the the base URL.



Top 50 recent answers are included