Hot answers tagged

19

There's often confusion between process forking and execution. When you do at the prompt of a bash shell. $ sh -c 'exec env ps' The process P1 issuing that $ prompt is currently running bash code. That bash code forks a new process P2 that executes /bin/sh which then executes /usr/bin/env, which then executes /bin/ps. So P2 has in turn executed code of ...


11

There are really two types of variable: Environment variables Shell variables To make things more complicated, they both look the same, and a shell variable can be converted to an environment variable with the export command. The env command will show the current set of environment variables. $ myvar=100 $ env | grep myvar $ export myvar $ env | grep ...


10

it seems Bash is a Turing-complete language The concept of Turing completeness is entirely separate from many other concepts useful in a language for programming in the large: usability, expressiveness, understandabilty, speed, etc. If Turing-completeness were all we required, we wouldn't have any programming languages at all, not even assembly language. ...


7

Yes, a program can know who its parent is. To illustrate, let's create two bash scripts. The first one reports its PID and starts the second script: $ cat s1.sh #!/bin/bash echo s1=$$ bash s2.sh The second script reports its process ID, the PID of its parent, and the command line used to run the parent: $ cat s2.sh #!/bin/bash echo s2=$$ PPID=$PPID ...


6

I don't see why that error would occur. In fact, I am reasonably certain there were more lines to the error than you show; for one thing, there's no actual error message. However, that regular expression won't actually match either of your example files. You are using [a-z]+\.mp3 which will only match lower case letters and, since you're matching all the ...


6

Why don't you use case? case $text in us-east-1|us-west-2|us-west-1|eu-central-1|ap-southeast-1|etc) echo "Working" ;; *) echo "Invalid option: $text" ;; esac


6

Yes, you may nest if-statements to your heart's content. The issue with your code is, as pointed out in comments to the question, the two exit statements. Taking a branch that triggers any of these will terminate the script. As far as I can see, both exit statements are superfluous and may be removed. You should also make a habit of double-quoting any ...


5

Why not make the life of the user a bit easier by not requiring them to type the name of the region at all? #!/bin/bash echo "Select region" PS3="region (1-10): " select region in "us-east-1" "us-west-2" "us-west-1" "eu-central-1" \ "ap-southeast-1" "ap-northeast-1" "ap-southeast-2" \ "ap-northeast-2" "ap-south-1" "sa-east-1" do if [[ -z $...


5

You can do that with -maxdepth option /bin/find /root -maxdepth 1 -name '*.csv' Also, check out find command examples in SO documentation


4

I recommend you read this article. There is a big difference between shell and environment variables. PATH is one of environment ones, and is already exported (by default), so by changing it, the current shell your using and all the others - any child shells or processes - will be affected. PATH is list of directories that the system will check when ...


4

Try double quotes for the outer ones: sed -i "/, false);/adefine( 'WP_MEMORY_LIMIT', '64M' );"


4

You can put the following lines in your vimrc to quit vim if any of its arguments are a directory: for f in argv() if isdirectory(f) echomsg "vimrc: Cowardly refusing to edit directory " . f quit endif endfor Alternatively, if you only want to quit if all arguments are directories, you can try something like this: let ndirs = 0 for f in argv()...


4

NO need for hard works, just change the /etc/bashrc file. I know, you may think that it only works on current tty but no mate, it works. Just exit once and then log in again with any user you like. You can even test this through SSHing or whatsoever. But if it didn't work - while I believe it does - read this file, this can help you much: /etc/profile


4

The problem is with this: [ "$text" != 'us-east-1' -o us-west-2 -o ... ] The -o means or and you need a full condition, so it would be [ "$text" != 'us-east-1' -o "$text" != 'us-west-2' -o ... ] See how we're having to test $text each time? Your logic is also wrong; you want -a (and); if it's not "us-east-1" and it's not "us-west-2" and it's not... ...


4

Assuming a shell like bash or ksh: max_time=3 SECONDS=0 IFS=$'\n:' grep -v '^#' ref.txt | while read tag cmd; do if (( SECONDS < max_time )); then echo "starting '$cmd' (tag is '$tag')" sleep 2 # for simulation purposes else echo "did not have time to start '$cmd' (tag is '$tag')" fi done This will give the ...


4

We can walk or swim anywhere, so why do we bother with bicycles, cars, trains, boats, planes and other vehicles? Sure, walking or swimming can be tiring, but there is a huge advantage in not needed any extra equipment. For one thing, although bash is Turing-complete, it is not good at manipulating data other than integers (not too large), strings, (one-...


4

Nested substitution is not available in any modern Bourne-like shells except zsh: $ print -rl -- ${$(echo):-C} C $ print -rl -- ${$(echo 1):-C} 1 In other shells: A=$(nc -l 443) A=${A:-C}


4

With non-GNU find: find /root ! -path /root -prune -type f -name "*.csv" This will prune (remove) all directories in /root from the search, except for the /root directory itself, and continue with printing the filenames of any file that matches *.csv. With GNU find: find -maxdepth 1 /root -name "*.csv"


3

Solution using Parameter Expansion for i in *.mp3 ; do mv "$i" "${i#${i%%[!0-9 ]*}}" ; done ${i%%[!0-9 ]*} deletes from first non-digit/non-space character till end. Remaining characters are passed to ${i# which then deletes them from beginning of i variable resulting in desired file name without starting digits and space


3

You can't force a shell process to use new aliases from the outside, so the request to load the new aliases will have to come from each shell instance on each terminal. You can make bash execute code after each command by putting that code in the PROMPT_COMMAND variable. So you could use something like reload_aliases () { . ~/.bash_aliases } ...


3

Some reasons not to use shell scripts for large programs, just off the top of my head: Most functions are done by forking off external commands, which is slow. In contrast, programming languages like Perl can do the equivalent of mkdir or grep internally. There's no easy way to access C libraries, or make direct system calls, which means that e.g. the ...


3

You redirect stderr to stdout, but you also need to redirect stdout itself. You're just missing the > and the order of redirection is very important. grub-mkconfig -o /boot/grub/grub.cfg >~/grub_error 2>&1 https://www.gnu.org/software/bash/manual/html_node/Redirections.html As for the difference between the console and terminal output (and ...


3

One portable way to remove such a file if only one exists: set -- "${FILE_PATH}/${FILE_NAME}"* [ $# -eq 1 -a -e "$1" ] && rm -- "$1" It seems to me that if you don't care how many of these 'ant' files exist beforehand, but want them (all) gone when you're done, just: rm -f "${FILE_PATH}/${FILE_NAME}"* -- that way, if there were no such files, ...


2

For the cases where it "works", you are leaving a process running cat which is reading its standard input, which has not been closed. Since that is not (yet) closed, cat continues to run, leaving its standard output open, which is used by the shell (also not closed).


2

This answer from Alex B at Stack Overflow will help you to rename both files and subfolders under a directory. It consists on using both find and rename Linux commands. I would only add that the command provided in the link above will modify directory names as well. In case that you want only to change file names, you need to change the -depth option with ...


2

Whenever you want to change one class of characters into another, use tr. for f in *; do test -f "$f" && echo mv "$f" "$( tr '[:upper:]' '[:lower:]' <<<"$f" )" done The script will rename all files in the current directory to all lowercase letters. It will skip directories. Remove the echo when you're certain it does what you want. ...


2

Try using fgrep (or the -F option to grep that does the same), and write your query without escaping the "<" and ">". I'd also suggest using single-quotes ' rather than double-quotes ", since the shell may expand what it think is variables and such when you use double-quotes. fgrep -i 'template <int N>' *


2

In Bash, the line A=${B:-C} will assign the value of the variable B to the variable A if B is set and not null. Otherwise the variable A will get the value C, i.e. the string containing the single character C. What you might want to do: B=$( some command ) A=${B:-C} After this, $A will either be the output from some command, if it's not null, or the ...


2

To avoid using eval: opt_file="" # Command line parsing bit here, setting opt_file to a # file name given by the user, or leaving it empty. if [[ -z "$opt_file" ]]; then outfile="/dev/stdout" else outfile="$opt_file" fi exec echo hi >>"$outfile"


2

Yes, if your shell supports process substitution (bash and ksh93 does) you may do like this: $ join file1 <( yourcommand ) This runs the join command with file1 and a file descriptor in /dev/fd connected to the standard output of yourcommand (which would be your curl thingy). Note that join expects all input to be sorted. It requires sorted input ...



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