New answers tagged

0

Unfortunately, there is no simple answer to this question. Many GUI things have no easy cli equivalent, and these days they are even more complicated due to things like dbus, udev, even systemd, and the use of xml instead of simple ini files. For some actions you may be able to see the result in your home directory. For example, create a timestamp file with ...


1

If the top and bottom are fixed, it can be something like: cat top.txt /dev/stdin bottom.txt > text.txt # with cat, - works the same as /dev/stdin or { echo 123 #top.txt cat echo 456 #bottom.txt } > text.txt followed by your compilation commands cat top.txt /dev/stdin bottom.txt > text.txt gcc whatever The first line should be a ...


2

As it is speed what you are looking for: We can do one host call with -t ANY instead of the four used now hoping to get all the four resolutions in one. That will need parsing of the answer. If the whois call could be started and while waiting for an answer from the whois servers we can make the host calls to the DNS servers, we can get the fastest ...


1

I'm not trying to outdo the accepted answer - there is a good answer already, but this was too long for a comment and I thought it might be useful. A significant speedup would result from reducing the 4 calls to host into one call to dig (or host, but the output is easier to handle from dig). Backgrounding the 4 calls will speed things up as the 4 calls ...


3

That's 4 uses of host and one of whois. The only way you could speed that up would be to run the commands as background jobs and arrange to check for their completion. That would be a rewrite, which the question declines. To make a background job of each, you'd do something like this, redirecting output to temporary files: ( host -t mx $inp ...


1

Another option is to be more specific about what you are grepping for. For example: whois stackoverflow.com | grep -E '^[[:space:]]*(Registr(ar|ant|y)|Sponsoring).*: ' This extracts only lines that begin with optional white space before either 'Registrar', 'Registrant', 'Registry', or 'Sponsoring', followed by any number (zero or more) of any character, ...


2

Use the -v flag: reg=`whois stackoverflow.com | egrep -i 'Registrar|Sponsoring Registrar|Registrant' | grep -v internic`


2

If files are exactly the same, then their md5sums will be exactly the same, so you can use: find A/ B/ -type f -exec md5sum {} + | sort | uniq -w32 -D An md5sum is always exactly 128 bits (or 16 bytes or 32 hex digits) long, and the md5sum program output uses hex digits. So we use the -w32 option on the uniq command to compare only the first 32 ...


0

It may be that the following is better suited to what you are trying to accomplish: # #// FILE could be a for-loop as well for example. FILE="bash_scropt.sh" ; if grep '#!/bin/bash' $FILE 1>/dev/null ; then printf "$FILE bash-script\n" ; else printf "> $FILE -- NOT bash\n" ; fi ; You can also mix this with @netmonk suggestion where a grep on ...


0

You can also use the standard ̀file command : [PRD][]user@localhost:~ 17:21:30 $ head -n 1 setproxymkt.sh #!/bin/bash [PRD][]user@localhost:~ 17:21:38 $ file setproxymkt.sh setproxymkt.sh: Bourne-Again shell script, ASCII text executable


1

Here's a fairly simple and straight-forward shell script that uses jsonpipe to do what you want. It doesn't use any fancy sh/bash features, and does only the bare minimum sanity checking of filenames. NOTE: jq is far more capable than jsonpipe, but jsonpipe is simpler and easier to use when you don't particularly care (or want to know) about the structure ...


1

You could periodically ping a website and execute your command when ping returns success. Something like the following... result=1 while [ $result -ne 0 ] do ping -c 1 www.google.com result=$? sleep 5 done mpg123 /home/user/file.mp3


3

Try this: #!/bin/bash while :; do ping -c 1 8.8.8.8 >/dev/null 2>&1 if [ $? = 0 ]; then break else echo 'No internet' fi sleep 1 done mpg123 /home/user/file.mp3 It will show you 'no internet' message if there is no ping response. And if it gets the response it will execute your command and quit.


0

This does what you ask for: [ "${OldIP:-"$StartIP"}" != "$StartIP" ] && echo "OK" As also this (more complex): ${OldIP:+false} || { [[ $OldIP != $StartIP ]] && echo "OK"; }


1

I think this will get you close. It will list out the cmp output for all files named results in A compared to all files named results in B. find ./A -name results | xargs -I REPLACESTR find ./B -name results -exec cmp REPLACESTR {} \;


0

If you are using bash, you can use a default substitution: [[ "${OldIP:=oldunset}" != "${StartIP?StartUnset" ]] && echo "OK" The syntax ${var:-def} will evaluate to either the current value of $var, or to the specified default (in this case, def) if the variable is unset or null. The value of the variable (if any) is unchanged. The syntax ...


0

I think your script is pretty efficient as is. You certainly aren't spending many cycles on this. Another way to write the logic: { test -n "$OldIP" || test "$StartIP" != "$OldIP"; } && echo OK This says "if OldIP is set or if OldIP and StartIP are different, then echo OK. Remember that [ is another name for test(1) which you can read about with ...


2

The seeming challenges of the question / request is perhaps the recursion aspect. Assuming that cmp is an adequate utility and that both folder / directories 1 & 2 to be compared are of the same structure (ie same files & folders) and reside within the same root path - you can try something similar to: #!/bin/bash ROOT=$PWD ; # #// change to ...


3

Try this script instead: #!/bin/sh sed -i -e "s/processors=[0-9]\+/processors=$(nproc)/g" ~/Scripts/test.sh sed is a Stream EDitor. -i switch tells it to make all changes inplace, -e though optional, tells that the following argument is a sed script


3

So many options, pick the one you like. Using grep: grep -o '^[^:]\+:[^:]\+' file.txt using cut: cut -d: -f1-2 file.txt using awk: awk -F: '{ print $1$2 }' file.txt using sed: sed 's/^\([^:]\+:[^:]\+\).*/\1/' file.txt using shell: while IFS=: read -r i j k; do echo "$i$j"; done <file.txt using perl: perl -pe 's/^([^:]+:[^:]+).*/$1/' ...


1

In general please AVOID using sshpass with a password. Everything you wrote can be observed by other users with the ps command and this SHOULD be of concern to you. Second problem there is here, I don't see you specifying -t option. This means you have disabled Defaults requiretty In your /etc/sudoers, which can have security implications. If you ...


1

value=55 size=42 declare -i result # set integer attribute result=$value-$size echo $result Output: 13


3

The [ ... ] syntax is actually a command, not anything special to the shell at all. It is another name for the test command—see man test or even just man [. What you want is arithmetic evaluation: delete="$((size-value))" What is happening in your code is that since you didn't quote the value you are assigning to the variable, that whole line was ...


0

You are trying to do math right? In that case, replace: delete=[ "$size" - "$value" ] with delete=$(($size-$value))


2

A "CLI tool that can follow the output of that specific file over some period of time" would be tail --follow=name --retry filename. It will print lines of the file as they are added, and will read from the start of the file if it gets removed and re-created, but unfortunately it may miss lines if the file gets truncated. Test 1: Terminal 1 (notice how it ...


1

So, guidance + trial and error led me to solution. I quoted the “$REPLY” variable as suggested…but I also needed to [[…]] instead of […] for the script to execute properly. I’m not exactly sure why, but now it’s working nonetheless. Thank you SE community!


2

If anyone want to hack on this some more, here are a messy though perhaps some hints or helps that catch interest. The procedure requests max height and width from file names to generate labels that fits. One feature missing is the vertical centering of the text (which, TBH, looks better.) To get width + height for a text (as integer) one way is to do: ...


2

I'm no ImageMagick expert, so there is probably a better way to do this, but you can do this in 2 steps, first adding the text to the left of each image into an intermediate file, then doing the montage. for file in foo*.png do convert "$file" -splice 100x0 -gravity west -annotate +10+0 '%f' /tmp/"$(basename "$file")" done montage -mode concatenate -tile ...


0

I found the preferred solution, using another channel.... #! /bin/ksh while read a <&3 do echo ------ $a ---------- echo weiter mit return read a done 3< abc


0

You mention that you're using scp inside your script to download packages. Your problem is with that bit. The issue is that, when you run ssh in this form: ssh user@host command ... there is no pseudo terminal allocated to the script that is running. scp tries to prompt for a password, but it needs a pseudo terminal for that, so without one, you get the ...


-3

Try this: ssh root@hostb 'bash -s' < local-script.sh


0

Is more -d -1 list good enough? Maybe in a script like: #! /bin/sh echo 'Check each line. Hit spacebar or enter to continue after each line.' echo more -d -1 list


2

Well, for one thing, you are running three separate external programs when one would be enough. You could do all the parsing and arithmetic in awk for example: xrandr --output LVDS-1 --brightness $(xrandr --prop --verbose | awk "/Brightness:/{print \$2 $1 0.1; exit}") The exit in the awk script ensures that it doesn't need to parse the whole output ...


1

If code is already working but running too slowly, the next step is to start profiling. When shell scripting, you can use time (try help time to see its help page) to see how long each command takes to run. I think bc should be very fast; sed against one line should also be very fast; and grep should be pretty quick, too, so I decided to try profiling the ...


4

You could use convert from ImageMagick: convert <input_image> -fill '#000' +opaque '#000' <output_image> What it does it changes all the colors not matching #000 to #000.


4

Would not be better if you compress your files and keep less of older logs instead of spending time creating a script? THIS is why logrotate exists. Take a look at your logrotate.conf. It should start with something like this: # see "man logrotate" for details # rotate log files weekly weekly # keep 4 weeks worth of backlogs rotate 4 # create new (empty) ...


0

awk -F, -v OFS=, '{ str[$1]+=$2; next } END { for (s in str) { print s, str[s] } }' filename builds an associate array (i.e. keyed by a string rather than an integer) containing the cumulative totals for each string (field 1). When it has read all of the input, it prints out each ...


0

How about bash: for i in $(cut -d ',' -f1 FILE | sort | uniq) do echo -n "$i", && echo -n $(grep "^$i," FILE | cut -d',' -f2 | paste -sd+ - | bc) echo $(echo "$i" | grep -E -o ",$") || echo done Or if you're going to miss ,: for i in $(cut -d ',' -f1 FILE | sort | uniq) do echo -n "$i", && echo -n $(grep "^$i," FILE ...


1

Easy in Perl: use a hash to store the running sums. perl -laF/,/ -ne ' $h{ $F[0] } += $F[1]; }{ print "$_,$h{$_}" for keys %h; ' input-file > output-file -n reads the input line by line -l adds newlines to print -a splits each input line into the @F array -F/,/ tells -a to split on commas }{ is the "Eskimo greeting" operator, it separates ...


0

find */ -type f -mtime -30 -print0 | sed -z -e 's:/.*$::' | sort -z -u | tr '\000' '\n' Requires GNU sort and GNU sed for the -z (NUL-separated input) options. find lists all files in subdirectories of the current directory less than 30 days old. output is piped into sed to remove everything after the first /, then into sort to unique ...


1

I would use find on each directory in turn, and pipe it to grep -q . to check if there are any results, and print the directory name conditionally upon whether or not there were any results: for d in */; do find "$d" -type f -mtime -30 | grep -q . && printf %s\\n "$d"; done


1

This might be not efficient but I hope it could help you find -mindepth 3 -maxdepth 3 -type f -mtime -30 | xargs -n 1 dirname | xargs -n 1 dirname | uniq # (or sort -u, I assume find's output is already sorted)


0

This is a revised version of Steven Penny's neat function. It prints its arguments in color and quotes them as needed. Use it to selectively echo the commands you want to trace. Since quotes are output, you can copy printed lines and paste them to the terminal for immediate re-execution while you are debugging a script. Read the first comment to know what I ...


0

#!/bin/sh read vstup if [ -z "$vstup" ] ; then : elif [ "$vstup" = "-" ] ; then vstup='' elif [ ! -f "$vstup" ] ; then printf "%s is not a regular file\n" "$vstup" exit 1 fi cat $vstup cat defaults to copying stdin to stdout if not given a filename (i.e. if $vstup is empty). It will keep doing so until user types an EOF character ...


0

This cron job does what you specified daily at midnight: 0 0 * * * script >/dev/null -c 'env TERM=vt100 mutt -F/dev/null -falerts -e "push <delete-pattern>syscheck@example.com<enter><sync-mailbox>y<enter><exit>"' /dev/null Let's break that down. script -c 'cmd' runs cmd under a fake pseudo-tty (pty) so that cmd thinks it ...


0

You should probably do some sort of delay loop (with a maximum iterations) that sleeps for 1 second, then checks whether the directory /dev/disk/by-label/backup_disk now exists. The following should work, but you may need to debug it. #!/bin/bash set -o errexit set -o unset $DIRECTORY=/dev/disk/by-label/backup_disk # do your reformat here until [ -d ...


1

You would have to do something like this, #!/bin/sh file="temp.txt" read -r vstup if [ -f "$vstup" ] then cat "$vstup" elif [ "$vstup" = "-" ] then while read line do # break if the line is empty [ -z "$line" ] && break echo "$line" >> "$file" done cat $file rm $file fi


1

A simple solution with read: I=0; while read -r; do ((I++)); echo "$I: $REPLY"; done< test.txt; where you can change test.txt to your script argument. If you don't want to use bash variable REPLY: I=0; while read -r LINE; do ((I++)); echo "$I: $LINE"; done< test.txt; or something else instead of 'LINE'


0

You can pipe the output through nl Example ls /etc | head | nl --number-separator=$':\t' --number-format=rz --number-width=4 0001: alternatives 0002: bash.bash_logout 0003: bash.bashrc 0004: bash_completion.d 0005: csh.cshrc 0006: csh.login 0007: dbus-1 0008: defaults 0009: drirc 0010: fonts If you want the separation between the ...


0

You could start by not instantiating Python on every matching byte (!): #!/usr/bin/awk -f function de() { getline < "/proc/uptime" close("/proc/uptime") return $0 } BEGIN { ec = de() } $0 == "ed" { getline byte1 getline byte2 number = strtonum("0x" substr(byte2, 2, 1)) + 2 data = ":: " de() - ec " ::ED." byte1 "." byte2 while (number--) ...



Top 50 recent answers are included