New answers tagged

0

This script works for me on macOS #!/usr/bin/env bash set -u # exit on undefined variable bash -c 'set -o pipefail' # return code of first cmd to fail in a pipeline # Print random open port. Inspired by # https://superuser.com/a/1041677/537059 CHECK="do while" while [[ ! -z $CHECK ]]; do PORT=$(((RANDOM % 60000) + 1025)) # ...


3

According to the manual 3.6.4 Redirecting Standard Output and Standard Error: 3.6.4 Redirecting Standard Output and Standard Error This construct allows both the standard output (file descriptor 1) and the standard error output (file descriptor 2) to be redirected to the file whose name is the expansion of word. There are two formats for redirecting ...


0

The process running the script exits, because it reaches the end of the script. It reaches the end of the script, because the command is run in the background with &.


0

When you start a process in the background (using &), it starts executing concurrently with its parent. Since your script does not have anything else to do, it exits and the orphaned process is adopted by init. When you do not use &, the parent waits for the child to finish, suspending itself. and you see the script as parent. In the latter case, ...


3

If your variables have the same number of lines then you could use the pr command to print standard output into two columns ex. $ printf '%s\n' "$varA" "$varB" | pr -2 -Ts^I Aug 01 04:25 Aug 16 03:39 Aug 26 10:06 where ^I stands for the TAB character (to be consistent with the default separator of the paste command) and may be ...


4

Here is my proposal if I understood correctly: for i in *.nc; do [[ "$i" =~ _([0-9]{8})[_.] ]] && d="${BASH_REMATCH[1]}" mkdir -p "${d:0:4}/${d:4:2}" mv "$i" "${d:0:4}/${d:4:2}" done


4

Looping through years and months: #!/bin/bash for year in {2001..2020} ; do mkdir $year for month in {01..12} ; do mkdir $year/$month mv gpm_cressman_${year}${month}* $year/$month done done In case you have too many files with long names per year & month (you claim "thousands"), bash might reach its limits ("argument list ...


4

Assuming the date is always in the same position in the filename, put this in a script: #!/bin/bash # while $# -gt 0 ; do file="$1" shift year="$( echo "$file" | cut -c 14-17)" mnth="$( echo "$file" | cut -c 18-19)" [[ -d $year/$mnth ]] || mkdir -p $year/$mnth echo mv "$file" ...


0

Not sure if this is of any use to anyone... This is the quick and nasty solution I came up with to sync files between two remote systems that the host is authorized to access, but where the remotes cannot access each other: (){ local RSYNC_TMP=$(mktemp); rsync -aP src-host:~/filename $RSYNC_TMP; rsync -aP $RSYNC_TMP dest-host:~/filename; rm -rf $RSYNC_TMP } ...


1

As people have already told you in the comments, this is a very bad idea. You will never be sure you've cleaned everything up and standard procedure for something like this is to wipe the sever and restore from a clean backup. That said, the reason your find command isn't working is because find doesn't understand extended globbing patterns like !("....


1

Instead of exepath=which exe (this command just runs exe, previously setting the environment variable exepath to literal value which) you should use exepath=`which exe` or exepath=$(which exe)


0

You can unload the completion system completely like this: zmodload -u zsh/compctl zsh/complete bindkey '^I' forward-word Instead of inserting completions, Tab will now accept the next word from zsh-autosuggestions. Before you give up completely on completions, though, may I suggest you give the zsh-autocomplete plugin a try? It gives you Visual Studio ...


0

In order to cancel all my slurm jobs (omitting the OP's grep 197), I found I had to prune the fist line of the squeue output, which contained column titles, also: squeue -u $USER | awk '{print $1}' | tail -n+2 | xargs scancel


-1

ls | tr '\n' '\n' >filename.txt This can save file names of the directory in the file.


0

How about this, sorry but I do not have many platforms to try it on local __shell=`ps $$ -o comm=""`


0

Put the lines MATLAB_HOME="/usr/local/MATLAB/R2018a/bin" PATH="$MATLAB_HOME:$PATH" into ~/.profile or ~/.bashrc


3

Many shells keep a record of commands which they have found on the PATH, so that they don’t need to explore all the PATH entries when a known command is invoked. You can see this e.g. on Bash or Zsh by running the hash command. Some shells such as Tcsh might only consider this record of commands: by default Tcsh scans the path when it starts, and when the ...


-1

Besides the link mentioned by @pLumo with various options I would suggest to consider to use pretty old but useful&powerful find. I use it a lot. With options like: -anewer File was last accessed more recently than file was modified. -cnewer File's status was last changed more recently than file was modified. -atime ... -ctime ... -mtime ... -amin/...


0

Indeed rmlint seems better suited for the task than rdfind. I like that it outputs a shell script, which you can examine to verify that it doesn't propose to do something you didn't really intend. For your use case, I was drawn to the section of the manual that talks about Flagging original directories, since you clearly have an "original" ...


1

scp -o User='foo@bar@baz#quux' host:/rpath lpath scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ -o User='DB6164@DB6164CP#example.net@y96553.example.net#22' \ PsmpDblanVip.example.net:/tmp/file.txt file.txt


0

Simply use the flag -L: From the man page: -L, --dereference dereference all symbolic links Then du calculates the size no matter whether they are symbolic or not.


1

Side-stepping the questions you've raised with a pragmatic solution, you can set up a default mapping for this target, which will simplify it for all ssh transport uses. I'm splitting DB6164@DB6164CP#example.net@y96553.example.net#22@PsmpDblanVip.example.net into user DB6164@DB6164CP#example.net@y96553.example.net#22 and CyberArk proxy PsmpDblanVip.example....


1

set -o extendedglob first_set=("$@[1,(i)^-*]") first=${(j[ ])first_set} would store in $first the concatenation of all arguments up to the first that doesn't start with - with one space character in between. Then for $second, you can get the rest: second_set=("$@[$#first_set + 1, -1]") second=${(j[ ])second_set} In any case, note that ...


2

In the first case, ls list the contents the /dev/fd -> /proc/self/fd -> /proc/<pid_of_ls>/fd, and in the second case, that of /proc/<pid_of_the_shell>/fd. While /dev/fd is a (magical) symbolic link to /proc/self/fd, . (the current directory, as listed by ls when called without arguments) isn't, and it was already resolved to /proc/<...


3

You can try this: shopt -s globstar for f in **/*.lri; do [[ ! $(find . -name "$(basename "${f%%.lri}").dng") ]] && realpath "$f" done


1

tl;dr: find . -name "*.txt" | perl -nle 's/\.txt$/.foo/; print unless -e' | cat -v Here's an example using Perl Note that we have a c.foo missing $ ls a.foo a.txt b.foo b.txt c.txt We can find it this way $ ls *.txt | perl -nle 's/\.txt$/.foo/; print unless -e ' c.foo c.foo is missing Update: dealing with filenames that contain ...


0

I had an issue where I could not login (on Ubuntu 20.04). I added the following tweak to huangzonghao's answer: # autoload tmux - place at EOF (end-of-file) within ~/.bashrc # if shell is interactive, and TMUX var is set... [[ $- == *i* ]] && [[ -z "${TMUX}" ]] && { tmux attach || exec tmux new-session && exit; }


1

you have files on jchab1:/scripts that match /scripts/* so ssh jchadb2 ls -l /scripts/*.sh first, expand localy to ssh jchadb2 ls -l /scripts/habak_trans.sh .. (no _v2 files) next, ls -l /scripts/habak_trans.sh .. is sent to jchab2 (and still no _v2. file) and on remote hosts, only explicit file are listed. compare ssh jchadb2 ls -l /scripts/*.sh and ssh ...


1

assuming you don't have any "newlines" in filenames, this should work: cd B find . -type f -print | while read f do [[ -f "A/$f" ]] || { echo mv "$f" "A/$f" ; continue; } cmp "$f" "A/$f" && echo rm "$f" done Run it, and if it looks good, remove the "echo" words ...


1

answer to your explicit question Yes, there is a way to script console interaction: Expect. Quite a few resources out there (https://core.tcl-lang.org/expect/index seems to be a good starting point); Exploring Expect by Libes (ISBN 9781565920903) is a fine book on the subject. A special case: if there is only one thing to enter from keyboard (say “foo”), ...


1

Using a shell expansion with a leading zero does what you need. #/bin/bash newdir="testing_$RANDOM" mkdir "${newdir}"; cd "${newdir}" for y in {2000..2022}; do for m in {01..12}; do touch "prefix_$y$m.txt" done done


0

You can use date for generating dates in shell with custom format $ date +%Y-%m-%d -d "2002-03-28 +1 days" 2002-03-29 $ date +%Y-%m-%d -d "2002-03-28 +1 months" 2002-04-28 $ date +%Y-%m-%d -d "2002-03-28 +1 years" 2003-03-28


1

I would start by challenging your requirements. You are trying to do everything in one step. You'd be much better off knowing what you want the restored system to look like before you start restoring files. It's actually easier to get the diff first than you might think. Step 1 Get the hash of every file on disk. You're going to have to do this anyway. ...


2

Here's a method that's simple, but inefficient if a lot of files are missing in A. Just do each step in turn. I assume that there are only directories and regular files (comparing metadata for special files is doable with a bit more work). Warning: untested code. First, copy files that are present in B but not in A to A. Preserve metadata (timestamps, ...


3

Step 2 and 3 seem the most difficult, so let's start with those. There is a tool called rdfind which finds duplicate files. You can decide what to do when a duplicate is detected: in your case you would want to delete it from B: rdfind -deleteduplicates true A B. If identical files exist in A and in B, the one from A is preserved. Other options are to ...


1

I want to do a binary search on all the extensions that I have loaded to isolate the problem one. Here's a solution that approaches this problem from a divide and conquer perspective. The basic idea is to prepare the input file a tiny bit, then recursively divide it in halves; each half is output as a sample command and then recurses on those halves. You ...


0

Do any of the common Linux utilities allow changing to arbitrary UID given CAP_SETUID? No, they don't. I know I could compile a small setuid(2) application, but it's cumbersome to transfer it into e.g. containers everytime I want to test user namespace functionality. If you plan to do your testing framework in bash, everything will be "cumbersome&...


1

It's not really clear exactly what you're trying to achieve. From your question you might be: Attempting to execute something as a different user for testing without the overhead of creating that user every time Attempting to run a process as a user that doesn't exist (with not matching entry in /etc/passwd or more precisely with getent passwd) Attempting ...


10

You need to enable extended globs for +([0-9]) to work. It's probably set in your bashrc, so is enabled in the interactive shell, but not in the script. Add shopt -s extglob to the script to enable it. See Pattern Matching in the manual. Without it, the pattern doesn't match, and ${var/pattern/replacement} leaves the value as-is.


0

You can use bash, instead of playing with Java. #!/bin/bash admins_mail=youraddress@example.com quota_exceeded=80 df -h | grep -vE 'hostname_or_IP_address:/mount/point|tmpfs|cdrom|Used' | awk '{ print $5 " " $1 }' | while read output; do status=$(echo $output | awk '{ print $1}' | cut -d'%' -f1 ) echo $status partition=$(echo $output | awk '{ ...


10

Stéphane Chazelas has an excellent answer on pointing out differences in syntax between narrowly POSIX-compliant shells and other shells, and other pitfalls. This answer will take a different approach. As a human it can be difficult to take a script written for bash, ksh, or some other shell with their non-POSIX extensions and safely translate the entire ...


16

I don't agree conditions are easier to make with ((...)) and [[...]] (assuming that's what you're referring to; note that those operators are not specific to bash and come from ksh) than the standard [ or test command. [[ ... ]] and (( ... )) have several problems of their own¹ and which are much worse than those of [. If your [ fails with an unexpected ...


-2

I'd say the most important thing to avoid is [[ ... ]]. Arithmetic in between (( ... )) probably doesn't work either. Make it a habit to put variables in quotes to avoid errors when a variable is not set, such as "$var". All operators, arithmetic or logical, are words with dashes such as -eq or -a instead of = or &&. Also use shellcheck.net ...


1

You can combine a couple of commands: $ cat /proc/$(xprop | grep PID | awk '{print $3}')/cmdline | tr '\0' ' ';echo xprop will wait until you click on a window. When you do, it prints the process id number and other info (grep and awk clean that up) and cat shows the file /proc/cmd/PID/cmdline which holds the command line, with arguments, but uses zero as ...


-2

You can do this very simply with the built-in bash operator -ef: [[ file1 -ef file2 ]] && echo Same If the condition evaluates to true (file1 and file2 are the same), then it prints "Same". Otherwise, nothing is output.


0

2020 answer Append # Calc c(){ echo "scale=2; $*" | bc -l } to your ~/.aliases, then $ c 1/3 .33 (The original issue has been solved multiple times already. However, the title "Simple command-line calculator" may require division to some decimal points. The use of the -l option with bc seems to give 20 decimal points, which is ...


4

If your shell is zsh (which AFAIK is the default in newer versions of macos), you can set the autopushd option (set -o autopushd in your ~/.zshrc) which will cause zsh to remember all the places (current working directories, changed with cd/pushd/popd) you've been. Then, you can see that stack with: dirs Or dirs -v, so see the index of each directory on the ...


1

How about this function? hg_fold() { local -a config mapfile -t config < <(hg debugconfig) local -a opts for i in "$@"; do opts+=( --config "${config[i-1]}" ) done opts+=( --exact -r 2024:8679fc70eae8 -r 2021:8b3257871eac -m "Fold" ) echo ...


2

A simple brute force approach that'll work in any awk in any shell on all Unix boxes: $ cat tst.awk s=index($0,"START") { $0=substr($0,s); f=1 } f { rec = rec $0 RS } END { len = length(rec) for (i=1; i<=len; i++) { char = substr(rec,i,1) if ( char == "{" ) { ++cnt } else if ( char == ...


1

With pcregrep: start_word='START' pcregrep -Mo "(?s)\Q$start_word\E\h*(\{(?:[^{}]++|(?1))*+\})" < your-file With zsh builtins: set -o rematchpcre start_word='START' [[ $(<your-file) =~ "(?s)\Q$start_word\E\h*(\{(?:[^{}]++|(?1))*+\})" ]] && print -r -- $MATCH Those use PCRE's recursive regexp feature, where (?1) above ...


Top 50 recent answers are included