Tag Info

Hot answers tagged

19

Rather than type your password multiple times you can make use of pssh and its -A switch to prompt for it once, and then feed the password to all the servers in a list. NOTE: Using this method doesn't allow you to use ssh-copy-id, however, so you'll need to roll your own method for appending your SSH pub key file to your remote account's ...


14

Expect can do that. From the Expect website: Expect is a tool for automating interactive applications such as telnet, ftp, passwd, fsck, rlogin, tip, etc. Expect really makes this stuff trivial. Expect is also useful for testing these same applications [...]" It comes with a lot of help, like autoexpect. Again from the Expect website, autoexpect ...


14

If the command is not very picky it should work with something like this: command > /dev/null << EOF <answer 1> <answer 2> <answer 3> EOF This requires that you know the exact answers beforehand.


5

If your script expects one prompt answered, or several prompts in which you can give the same answer, there's yes: NAME yes - output a string repeatedly until killed SYNOPSIS yes [STRING]... yes OPTION DESCRIPTION Repeatedly output a line with all specified STRING(s), or `y'. Use it like this: yes Me | give_a_hug.sh


5

grep is a program that searches for regular expressions. The first argument for grep is the pattern to look for. In scripts and functions $1 is a reference to the first argument passed to that script or function. The ^ prepended to the argument is a standard regular expressions modifier that matches the beginning of a line -- this way you can ensure that ...


5

Alternative using xargs, sshpass and ssh-copy-id: Assuming your credentials living in credentials.txt in format user:password@server: $ cat credentials.txt root:insecure@192.168.0.1 foo:insecure@192.168.0.2 bar:realsecure@192.168.0.3 You could do: tr ':@' '\n' < credentials.txt \ | xargs -L3 sh -c 'sshpass -p $1 ssh-copy-id $0@$2' Note: ...


4

No need for bash here, any standard sh interpreter implementation will do: #! /bin/sh - ret=0 for file do dir=$(dirname -- "$file") case $dir in (*[!/]*) dir=$dir/ # handle / and // specially esac base=$(basename -- "$file") name=${base%.*} name=${name:-$base} # don't consider .bashrc the extension in /foo/.bashrc ext=${base#"$name"} ...


4

The Theory The rules are : inside a ' delimited string, nothing gets interpreted and anything but a ' doesn't have special meaning. This means that only a ' need escaping but it also mean that, in order to escape it, you need the '\'' construct. (The first ' ends the string, the following \' adds a literal ' (the escape prevents the start of a new string) ...


4

#!/bin/sh - urldecode() { python -c "import sys, urllib as ul;print ul.unquote_plus(sys.argv[1])" "$1" } str="this+is+%2F+%2B+%2C+.+url+%23%24coded" decoded=$(urldecode "$str"} printf '%s\n' "$decoded" That is: avoid aliases in scripts as that's not guaranteed to work (some sh implementations like bash ignore aliases when non-interactive) quote your ...


4

ClusterSSH gives you a window on each machine and with a common window to control all windows. If we are talking 10 machines this will work. If we are talking 100 machines, there will be to many windows. The beauty of ClusterSSH is that if one machine is not 100% like the rest, you can just click the window, and send keystrokes only to that machine before ...


3

There's no error with head -n 2; you can check that by removing the | and the subsequent code. The problem is that the code between the braces is only executed once - it's not a loop. And read only reads data from a single line of input. So you need to make some sort of loop to print data for multiple files. You could use a while loop, or you could take ...


3

Without &, the script that you're executing remotely says “change to /root/myDir, then execute gedit and wait for it to exit”. The variant with & says not to wait for gedit to exit. Either way, the shell exits once it's executed the last command in the script. If you want to execute a script and then execute more commands that you type ...


3

The quick answer is checksum="${checksum% || })" instead of checksum+=")". Just unconditionally add the || string in each step and then strip off the last unnecessary one at the very end (so the line_number computation is no longer needed). A better way to do this is awk -F, 'BEGIN { printf "md5( " } toupper($2) != "DATE" { printf "%s%s", sep, ...


3

Assuming you are using bash (or zsh) and your mail agent is sendmail then: [[ -f "filename_$(date '+%m%d%Y')" ]] || echo "File is missing!" | sendmail myname@gmail.com Between [[ and ]] we test if file exists, and if not then print some message and send it to myname.


3

To select shared lines in all files you can use grep (out.txt) grep -ho ' [0-9] [a-z] ' file3 | grep -Fof - file2 | grep -Ff - file1 select operatable field (as variant cut -d' ' -f3,4 file3) and use it to search it in next file2 and file1. As usual for joining 2 file use join command (surprise!) (out2.txt) join -j 3 <(sort -k3,4 file1 | sed 's/ ...


3

You might want to check this site about diff3 with this program you can compare 3 files as sample output: $ diff3 parent.txt your.txt mine.txt ==== 1:1,2c Hello, This is parent file. 2:1,2c Hello, This is your file. 3:1,2c Hello, This is my file. You can use diff3 file1.txt file2.txt file3.txt > output.txt


3

Using Ansible is fairly simple. Just replace <USER> with the real login name $ cd /path/to/public/key $ cat<<END > hosts host1.example.com 10.10.10.10 END $ ansible -i hosts all --ask-pass -u <USER> -m authorized_key -a "user=<USER> key='$(cat id_rsa.pub)'"


3

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


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.


2

You can avoid to use eval source /tmp/config.txt counter=1 line0="machine$counter[0]" echo ${!line} And much better to call echo via loop for counter in 1 2 3 do line="machine$counter[@]" for element in "${!line}" do echo $element done done


2

Use the eval command. eval "echo \${machine${counter[0]}}" Notice that the first $ is escaped so that it isn't evaluated until eval processes the string. The way this works is that eval executes a command the same as if you had typed it at the command prompt. The difference is that the command that is executed can be constructed programmatically. So in ...


2

Possible solution with awk (I will edit if needed because it is a little unclear from your question what are exact requirements): awk 'FILENAME == ARGV[1] { m[$2,$3] = 0; z[$2,$3] = $5; next; } FILENAME == ARGV[2] { if (($2,$3) in m) { m[$2,$3] = 1; z[$2,$3] = $5 " " z[$2,$3]; } next; } { if (($2,$3) in m && ...


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"


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

Open up root's crontab with: sudo crontab -u root -e And create a new cronjob by appending this line to it: 60 * * * * find / -type f -iname "*.xls" -mtime +30 -exec rm -f {} \; &>/dev/null With this you have created a cronjob that will be executed every hour and search your system with find for files with a .xls extension and is +30 days old, ...


1

I'll say what I always do. Please NEVER use regular expressions to parse XML. It's bad news. XML has some various formatting which means semantically identical XML will match or not match certain regular expressions. Simple things like line wrapping, unary tags, etc. This means you create brittle code, which one day might mysteriously break because of an ...


1

Compact Script Assuming the xml is in file.xml, just do: sed -r 's/("base64">)([[:graph:]]+)/\1'"`grep -oP '"base64">\K[[:graph:]]+' test | base64 -d`"'/g' file.xml This is a compact regex, which will do the task. Let me break it down and explain. Break Down First I select the base64 string using grep and decode it: grep -oP ...


1

I don't understand how the %\.* is removing the file extension That's because it doesn't. :) The code as written is wrong, and it doesn't accomplish anything useful. There is a standard shell expansion ${variable%pattern}, which takes $variable, and removes the shortest chunk at the end of it that matches pattern (there is a similar expansion ...


1

First, note that the current directory in a crontab is your home directory. You should put the full path to the script in the crontab. However, since your script is being executed, this isn't the problem. The likely problem is that your script requires an environment variable that is set in your normal session. Cron jobs run with a minimal environment, your ...


1

Here is your script fixed to work the way I think you meant it to work: i=1 while read line; do while :; do var=$( echo $line | cut -d ':' -f$i ) i=$( expr $i + 1 ) [[ "$var" != "" ]] || break echo $var done done <$1 A couple of remarks: i was not ...



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