New answers tagged

0

Thanks to @stéphane-chazelas who pointed out problems with my previous attempt, this now seems to work apart from embedded newlines which are removed altogether :-( serialise_array() { set -- "${@//\\/\\\\}" # \ set -- "${@// /\\ }" # escape space set -- "${@//$'\n'/$'\\\n'}" # newline set -- "${@//$'\x08'/$'\\\x08'}" # backspace set -- ...


0

I had a similar situation and used (abused?) gpg with public/private key encryption. The nice thing is that on most systems things are set up so that the access restricting password for a particular key is kept for 5 or 10 minutes, so you only have to type the password once then can go keep on using it and on non-use it will expire, much like sudo You can ...


0

Here you go: #!/bin/bash newTS=`date +%s` if test -r ~/.password then . ~/.password else TS=0 fi if test `expr $newTS - $TS` -gt 900 then # outdated password record rm -f ~/.password printf "Please enter your password: " read password printf "export TS=$newTS\nexport password=$password\n" > ...


1

Direct answer The unquoted command: echo a b c, will be split on (metacharacter space) no matter what IFS is or is not. The split arguments to echo: a, b and c will be printed with spaces because echo is defined as this: LESS=+/'^ *echo \[-neE\] \[arg ...\]' man bash Output the args, separated by spaces, followed by a newline. Also no $IFS involved. ...


0

Under set -e, the non-existence of failfailfail causes the whole script to exit (or the subshell, if the function is executed in a subshell). If you don't need to modify the shell state from the function, you can run it in a subshell. myfunc() ( set -e ls failfailfail uptime ) Another approach in bash is to set an ERR trap to execute ...


3

Process substitution <(…) creates a pipe, uses /dev/fd to give a path that's equivalent to the file descriptor where the pipe is, and passes the file name as an argument to the program. Here the program is sudo, and it passes that argument (which is just a string, as far as it's concerned) to wpa_supplicant, which treats it as a file name. The problem is ...


2

If I understand correctly, you want to create a level of indirection, where the program that you specify through a shebang in a script is itself a script with a shebang. Linux accepts nested shebangs, but other Unix variants don't. So you can put #!/home/me/groovy/groovyrun at the top of your Groovy scripts and #!/bin/sh at the top of ...


0

If you're running under set -e, add || true after a command to ignore a failure of that command. pids=$(pidof /usr/bin/Xvfb || true) if [ ! -n "$pids" ]; then Xvfb :0 -screen 5 1024x768x8 & fi But since pidof returns a nonzero status if no processes are found, you could directly test its return status instead of checking whether its output is ...


0

The shell running in the terminal receives the script that you're pasting on its standard input, and your script itself reads from standard input. There's a conflict here: your script will end up reading a bit of itself. If you don't get a sudo prompt, then what happens is: The shell reads whole lines until it has a complete command. The first line starts ...


0

If you don't have dos2unix this is a way to fix this issue. cp script _p4 && tr -d '\r' < _p4 > script && rm _p4


0

I believe I have a solution for you. Recently I have installed Kali Linux on my machine and I noticed a similar issue. Executing the following sudo apt-get install linux-headers-$(uname -r) will only fetch form the repositories in your sources.list file. Now in my case the repositories that I have available are outdated therefore I resulted to installing the ...


2

An excerpt of irb's manpage on Debian "Jessie" 8: -r library Same as `ruby -r'. Causes irb to load the library using require. For your example, just use the following command: irb -r my_gem


0

Try apt-cache search linux-headers or install Synaptic. See How do I search for available packages from the command-line?. Be aware that if no headers exist for whatever uname -r returns, you will need to upgrade, or downgrade, your kernel until you have a matching set.


0

A solution - not one that is as elegant as those that change the *RS variables, but perhaps reasonably clear: PATH=`awk 'BEGIN {np="";split(ENVIRON["PATH"],p,":"); for(x=0;x<length(p);x++) { pe=p[x]; if(e[pe] != "") continue; e[pe] = pe; if(np != "") np=np ":"; np=np pe}} END { print np }' /dev/null` The entire program works in the BEGIN and END ...


3

The >> /tmp/output already sends all output to the file, leaving nothing to be sent to tee. So the command should read node test.js 2>&1 | tee --append /tmp/output.


0

To replace a space with a tab character using $IFS you can use the argument array: unset IFS set a b c IFS=$(printf \\t) printf "$*\n" Understand that $IFS is about splitting - it contains a list of characters the shell uses to split unquoted expansions in list contexts. You can't really use it to replace characters except in the special case of the $* ...


3

Newlines are handled specially by bash, regardless of the value of IFS. A backslash before a newline causes the newline to be ignored. Has nothing to do with word splitting and would occur even if IFS were set to some custom value. From LESS=+/^QUOTING man bash: A non-quoted backslash (\) is the escape character. It preserves the literal value ...


5

In: echo $IFS you did not double quote variable, the variable content under affect of glob+split operator in all Bourne-like shells, except zsh: echo glob(split($IFS)) The characters in IFS itself are used for splitting, so $IFS expanded to nothing, you only got an empty line from echo. When you double quote "$IFS", the content of IFS was passed to ...


2

Your format string to date is wrong. %I gives the hour in 12 hour format (01..12), you probably want %M, and then your command seems to work (on this linux box - I don't have a synology to try on).


5

Eric Blake answered on the bash-bugs mailing list: jobs is an interesting builtin - the set of jobs in a parent shell is DIFFERENT than the set of jobs in a subshell. Bash normally creates a subshell in order to do a pipeline, and since there are no jobs in that subshell, the hidden execution of jobs has nothing to report. Bash has code to ...


3

For python at least I recomend "Learn Python The Hard way", by Zed Shaw. Freely available online. Good stuff. Not sure if posting a link here is technically advertising... Here goes. Free Book


2

There are many. I can suggest two for python: codecademy: to learn syntax and get a basic understanding of the langauge newcoder.io: some projects to go further


0

Given that they are all simple commands, you could do it something like the following: myfunc() { ls && failfailfail && uptime || return $? }


0

The only way you can make it simpler is by combining it all in one command but it makes the script a bit harder to maintain than your last version: myfunc() { ls && failfailfail && uptime || return $? }


0

rush has a nice one-liner solution; here's a simple bash function that prints out all of the matches in the string: function pratappos() { target=$1; shift pos=1 while [[ $# -gt 0 ]] do [[ "$1" = "$target" ]] && echo $pos shift; ((++pos)) done unset target pos } It's generalized to search for any string in a given list, so for ...


1

The problem is here: '-15 minutes "$n"' Single quotes stop variable substitution, so you're literally passing "$n" in rather than the contents of the variable. Write: /opt/bin/date --date "-15 minutes $n" '+%Y-%m-%dT%H:%I:%S' instead.


3

To avoid running one dig and read per line of the file, you could do: dig -f domains.txt mx +noall +answer Which would give an output like: stackexchange.com. 300 IN MX 5 alt1.aspmx.l.google.com. stackexchange.com. 300 IN MX 1 aspmx.l.google.com. stackexchange.com. 300 IN MX 10 ...


1

The pipe character | is a meta character because it ends a word that is not quoted. This is needed to make the shell language easy to understand. The way shells create the various processes for a pipeline is not standardized and differs between implementations. The Bourne Shell originally did create a sub-shell that then becomes the parent of all ...


2

It's worth observing that the shell must establish redirections before starting the program. Consider your example: ./write_file.py >> ~root/log What happens in the shell is: We (the shell) fork(); the child process inherits the open file descriptors from its parent (the shell). In the child process, we fopen() (the expansion of) "~root/log", and ...


1

The line in your code weka $1 ${search["$1"]} is being subject to shell spliting. If you have not changed the variable $IFS that splitting will happen on spacetabnew line. The line gets expanded to: weka $1 ${search["$1"]} weka a -search "a params" -search "other a params" But getting split as described above, this is what it means: <weka> ...


1

The shell does not handle quoted quotes the way that you want. (Once the quotes are quoted, they are treated like regular characters.) You can trick bash into doing what you want. To start define an associative array: declare -A s s=( ["a"]='-search;a params;-search;other a params;' ["b"]='-search;just these params' ) As you can see, the string has the ...


3

A suitable answer depends on how the names might vary. You could transform the names using the shell's built-in parameter substitution if you assume constant field-widths. That's relatively limited in scope. More interesting would be using character classes in sed: newname=$(echo "$oldname" | sed -e 's/^\([[:alpha:]]\+\)\([[:digit:]]\+\)_/\1-\2-/') ...


2

If all starts with ABS1789_2563- for f in ABS*; do mv "$f" ABS-1789-2563-${f:13}; done Here ABS-1789-2563- is simply hard coded under the assumption all your folders starts with ABS1789_2563-. ${f:13} expands to the end of parameter $f starting from offset 13 - often referred to as substring. In bash Substring Expansion. See 3.5.3 Shell Parameter ...


5

IFS="\n" # Handle files with spaces in the names for file in ABS*; do newfile="${file/ABS/ABS-}" # Add the hyphen following ABS newfile="${newfile/_/-}" # Change the underscore to a hyphen mv "$file" "$newfile" # Make the change done In light of Tony's comments below, a more general use version could be as ...


1

As stated by steeldriver, if you use GNU sed, you can tell which occurrence should be replaced, e.g.: echo "/test/test/ 12 /test/test" | sed -n -e 's_/._/_2 p' If you can not make use of this feature you can also write: echo "/test/test/ 12 /test/test" | sed -n -r -e 's_(/[a-z]([a-z]+))\1_\1/\2_ p' Biliography: http://www.grymoire.com/Unix/Sed.html ...


0

The problem is because you have the script file under a non-unix format you can use: vi new_name_for_your_script and do a copy-paste ( you're running over windows ) your problem will be solved.


1

It's possible if you use two non-portable things: GNU awk's two-way I/O (see relevant StackOverflow answer); millisecond output with date (see this ServerFault answer). With that, you can prefix the input with timestamps like that: awk '{"date +%Y%m%d%H%M%S%3N" |& getline timestamp; print timestamp,$0; close("date +%Y%m%d%H%M%S%3N")}' ...


1

echo $(hostname) does not work, as you already realized, since the command is expanded. Use single quotes ' to prevent command expansion: echo '$(hostname)'


-1

It should work if you specify the shebang in your groovyrun script. As a quick experiment, create shell1 containing #!/bin/sh echo shell1: "$@" sh "$@" and shell2 containing #!/.../shell1 echo shell2: "$@" (with the correct path to shell1); running shell2 Hello then produces shell1: ./shell2 Hello shell2: Hello As you can see, the parameters passed ...


3

Quoting the ArchLinux wiki: Note: Because of the process substitution, you cannot run this command with sudo - you will need a root shell. You should be able to use su -c under sudo like so: $ sudo su -c 'wpa_supplicant -D nl80211,wext -i wlp4s0 -c \ <(wpa_passphrase "some ssid" "password")'


0

I tried the following on a jessie pi and had no problem with stdbuf -oL in front of hexdump working as intended. while sleep .5;do echo -n x;done | stdbuf -oL hexdump -v -e '1/1 "%02x\n"' | ts %.s | cat The while is to simulate slow input, ts timestamps each line, and the cat is just to provide another pipe. The output is regular and the timestamps differ ...


0

I’m using zsh and this function works well for me: function grep1() { tee > >(head -n 1) > >(tail -n +2 | grep $*) } The main advantage of this approach is that you have full control over the grep command, so you can pass the usual flags like -i, -E, etc. Usage example: $ ps -rcA | grep1 databases PID TTY TIME CMD $ ps -rcA ...


1

The first point of call would be man date There you may find the details on setting time with a relative offset, as in date --date '-15 minutes 2016-04-27T14:14:47.836Z' It also offers details about how to format the output.


1

The POSIX standard defines that $$ always is the pid of the main shell. If you run a process in the background, $! returns the pid of the last background process.


1

Answer here: What does !#:3 mean in a shell command Basically, you can use it to shorten a command in combination with ':n', so: $ cd /home/me/some/super/deep/dir/that/i/do/not/want/to/type/again ; ll !#:2 Of course this is a bit silly example, because you could just do ll, but you get the idea, it can be used in sh scripts.


0

I'm sorry to inform you that it is quite the opposite. The shell needs to open it's I/O first and then passes control to the program. tee might prove helpful in this case: ./write_file.py | tee -a ~root/log > /dev/null


10

From the bash man page, section REDIRECTION (emphasis by me): Before a command is executed, its input and output may be redirected using a special notation interpreted by the shell. ... A failure to open or create a file causes the redirection to fail. So the shell tries to open the target file for stdout, which fails, and the command isn't ...


16

It's not really a question of ordering checks, simply the order in which the shell sets things up. Redirections are set up before the command is run; so in your example, the shell tries to open ~root/log for appending before trying to do anything involving ./write_file.py. Since the log file can't be opened, the redirection fails and the shell stops ...


1

This is the closest you can get: your_main_command && run_on_success || run_on_failure The caveat is that run_on_failure will be run if any of the preceding commands i.e. you_main_command or run_on_success fails.


2

Yes, It's possible [[ "a" == "a" ]] && echo true || echo false Try replacing "a" with "b", to see false: [[ "b" == "a" ]] && echo true || echo false



Top 50 recent answers are included