Tag Info

Hot answers tagged

16

-eq is an arithmetic operator, which compares two numbers. Use ==, =~ or = instead. Also use quotes, because if ${PACKAGENAME} contains a whitespace, then it will be split into multiple arguments, which causes to make [ see more arguments than desired. See here a list of common bash pitfalls. if [ "${PACKAGENAME}" == 'kakadu-v6_4-00902C' ]; then echo ...


14

Try: for x in {a..z} ; do mkdir -p $x/${x}{a..z} ; done Bash will expand XXX{a..z} out to XXXa, XXXb, and so on. There's no need for the inner loop you have. After that: $ ls a b c d e f g h i j k l m n o p q r s t u v w x y z $ ls m ma mc me mg mi mk mm mo mq ms mu mw my mb md mf mh mj ml mn mp mr mt mv ...


11

Generally, you only have to escape one time to make special character considered literal. Sometime you have to do it twice, because your pattern is used by more than one program. Let disscuss your example: man gcc | grep \\. This command is interpreted by two programs, bash interpreter and grep. The first escape causes bash knows \ is literal, so the ...


7

You really are not going to be able to do this with a simplistic sed script. I’m assuming that you will want to reduce to “citation forms”, collapsing all inflections into a base form. That means that adjectives like protégé, protégés, protégée, protégées all count as the same thing, the base adjective/participle protégé. Similarly, all inflections of ...


6

This usually happens when the shebang (#!) line in your script is broken. The shebang is what tells the kernel the file needs to be executed using an interpreter. When run without sudo, the message is a little more meaningful. But with sudo you get the message you got. For example: $ cat test.sh #!/bin/foo echo bar $ ./test.sh bash: ./test.sh: /bin/foo: ...


6

How about these two: $ sudo dmidecode -t 4 | grep ID | sed 's/.*ID://;s/ //g' 52060201FBFBEBBF $ ifconfig | grep eth1 | awk '{print $NF}' | sed 's/://g' 0126c9da2c38 You can then combine and hash them with: $ echo $(sudo dmidecode -t 4 | grep ID | sed 's/.*ID://;s/ //g') \ $(ifconfig | grep eth1 | awk '{print $NF}' | sed 's/://g') | sha256sum ...


6

So, with bash's alphabet expansion thing, this works: set {a..z} for a do printf "./$a/$a%s\n" "$@" done | xargs mkdir -p And if you just type out the alphabet once in the first line the same concept should be portable to any shell. There are other ways to arrive at the set line if you don't want to type it like: seq -sP32P 97 123|dc a b c d e f g h i j ...


5

Replace -eq with == so your if block would be this:- if [ ${PACKAGENAME} == kakadu-v6_4-00902C ]; then echo "successfully entered if block!!" fi


5

Try: echo "/mnt/VPfig/Amer/AR4/Celtel/files/COM.txt" | sed 's|^/[^/]*||' which gave me: /VPfig/Amer/AR4/Celtel/files/COM.txt It looks for the first / followed by as many non-/s as possible, then replaces them with an empty string.


4

Many modern distributions ship a file /etc/machine-id containing a most probably unique hexadecimal 32-character string. It originates from systemd, where a manpage has more information, and may be appropriate for your purpose.


4

Firstly, please note that the CPUID is definitely not a commonly accessible uniquely identifying marker for any system later than an Intel Pentium III. While hashing it with MAC addresses may lead to unique markers certainly, this is due only to the unique qualities of the MACs themselves and the CPUID in that case is nothing more than circumstantial. ...


4

On a system, the only thing that is really persistent is a file. That's pretty much what you should use. Here's an solution using an init.d script. Let's consider the following (simple) script, /etc/init.d/myupdate : #! /bin/sh ### BEGIN INIT INFO # Provides: myupdate ### END INIT INFO PATH=/sbin:/bin:/usr/sbin:/usr/bin case "$1" in start) ...


4

You can leverage the printf builtin. mo1 () { for file in *.txt; do grep -n -C1 "$(printf "%s.*" "$@")" "$file" done } This simple version inserts .* after the last element. It doesn't matter for this specific use case, but in other cases (e.g. grep -o) you may need to strip off the extra .* at the end. mo1 () { pattern=$(printf "%s.*" "$@") ...


4

A GNU awk solution that treats , or \n as a record separator and - as a field separator. An equality check or a range check is applied depending on number of fields awk -v num=348 -v RS=',|\n' -F'-' 'NF == 2 && $1 <= num && $2 >= num{c++}; NF == 1 && $0 == num{c++}; END{print c+0}' file 2


3

Your problem is that the script in your .../bin directory is execed in another shell environment - its environment does not survive its execution and so the x() { ... ; } definition does not survive into the current shell environment when it completes. When you . ./somescript.sh (or source in some shells such as bash and zsh) the current shell reads the ...


3

With this simple loop you can automate it and spread to all remote servers. #!/bin/bash for ip in `cat /home/list_of_servers`; do ssh-copy-id -i ~/.ssh/id_rsa.pub $ip done


3

Another way is to negate them: : ${PACKAGENAME:?'$PACKAGENAME variable is empty!'} #emits error and exits [ -z "${PACKAGENAME#kakadu-v6_4-00902C}" ] || { #if var - str not empty do block echo '$PACKAGENAME is not kakadu-v6_4-00902C' exit 1 } >&2 The above block first tests if "$PACKAGENAME" has any value at all, and, if not it exits with ...


3

In a POSIX shell: $ x='/mnt/VPfig/Amer/AR4/Celtel/files/COM.txt' $ printf "/%s\n" "${x#/*/}" /VPfig/Amer/AR4/Celtel/files/COM.txt Explanation The parameter expansion ${x#/*/} removes the leading component of the path with the two /s enclosing it and the printf tacks a leading / back on.


3

Natural language processing is complex. Doing it with regular expressions is like parsing HTML with regular expressions, only worse. Read tchrist's excellent answer for some insight as to how to use approach your problem. I'm going to briefly answer the part about the portability of your use of unix text processing tools. The common denominator to all ...


3

If you can use perl: $ perl -F',' -anle ' for (@F) { ($l,$h) = split "-"; $count++ if $l == 348 || ($l < 348 and $h >= 348); } END {print $count} ' file 2


2

I bet there'll be better ones but here's my go: If the config file has parameters on their own line sed -i '/ValueTwo/s/= .*$/= 22222/' config_file This will replace the contents of config_file in-place. To create a new file with the parameter changed, remove -i and place > new_file at the end of the line. If your config file has parameters on the ...


2

There is no need to use eval in this instance eval $i forces eval to evaluate the contents of i as a command - this is why you see errors such as b: command not found being reported A better way would be to print parameter values with bash using variable deferencing for i in a b c; do echo "$i=${!i}"; done a=1 b=2 c=3


2

Since no input example is given, I'm going to assume a very basic patern: Uesrs groups a p,r,t b p,q In that case you have several options, because usermod -G can use the second column natively. something like while read line do usermod -G "$(cut -f2 -d" ")" $(cut -f1 -d" ") done < users.txt The while loop reads each line from users.txt, and ...


2

The simplest way would be to remove the shortest string of non-/ characters from the beginning of the string. In most regular expression languages, [ ] os a character class that matches anything within the brackets. [abc] will match either a or b or c. [^ ] is a negated character class, matching anything except the characters in it. So, [^/]* will match ...


2

while read -r line; do mkfs.ext4 "$line" done < <(df -k | grep 'media' | cut -d ' ' -f 1) The df command with the grep and cut pipes would give us the list of external hard drive mounts. For instance, the external hard disk will always get mounted automatically to /media in most of the systems. So, I am using df command to check the mounts of the ...


2

If you use a custom shell as suggested by Arcege and 2bc, then that shell will receive the command which the user intends to execute as an argument because the shell is invoked like this: shellname -c the_original_command So ignore the -c (that your $1) and find the command in $2. For example: #!/bin/sh case "$2" in on) do something ...


2

The specific error you are getting is because your script is also processing the header of your file. An easy fix would be to skip lines that begin with a #: #!/bin/bash if [ ! -f "$1" ]; then echo "No file found" exit 1 fi ## Use grep -v to print lines that don't match the pattern given. grep -v '^#' "$1" | while read -r LINE || [ -n "$LINE" ]; do ...


2

This answer will provide the fields that contain the specified number, not just the lines, if you are after that level of detail (and if the ranges in your data might contain overlaps): awk -v num=348 -F, '{ for (i=1; i<=NF; i++) { if ($i == num || (split($i, a, /-/) == 2 && (a[1] <= num && num <= a[2]))) { print $i ...


2

Assuming each line of arguments.txt represents a separate argument, with bash 4 you can read arguments.txt into an array using mapfile (each line from the file goes in as an array element, in sequence) and then pass the array to the command mapfile -t <arguments.txt source test.sh "${MAPFILE[@]}" The advantage is that splitting on spaces embedded ...


2

Recursion is rarely the answer to anything :-) What you are trying to do can be done via a simple loop while :; do ssh $host done Whenever ssh exits, the script will go to the next iteration of the loop, and re-execute it. In while :, the : is a noop command that always returns a true value, so the while will never end. If you need some way of ...



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