Posts

Showing posts with the label Shell

Checking For A Dirty Index Or Untracked Files With Git

Answer : The key to reliably “scripting” Git is to use the ‘plumbing’ commands. The developers take care when changing the plumbing commands to make sure they provide very stable interfaces (i.e. a given combination of repository state, stdin, command line options, arguments, etc. will produce the same output in all versions of Git where the command/option exists). New output variations in plumbing commands can be introduced via new options, but that can not introduce any problems for programs that have already been written against older versions (they would not be using the new options, since they did not exist (or at least were not used) at the time the script was written). Unfortunately the ‘everyday’ Git commands are the ‘porcelain’ commands, so most Git users may not be familiar with with the plumbing commands. The distinction between porcelain and plumbing command is made in the main git manpage (see subsections titled High-level commands (porcelain) and Low-level commands...

#!/bin/sh Vs #!/bin/bash For Maximum Portability

Answer : Solution 1: There are roughly four levels of portability for shell scripts (as far as the shebang line is concerned): Most portable: use a #!/bin/sh shebang and use only the basic shell syntax specified in the POSIX standard. This should work on pretty much any POSIX/unix/linux system. (Well, except Solaris 10 and earlier which had the real legacy Bourne shell, predating POSIX so non compliant, as /bin/sh .) Second most portable: use a #!/bin/bash (or #!/usr/bin/env bash ) shebang line, and stick to bash v3 features. This'll work on any system that has bash (in the expected location). Third most portable: use a #!/bin/bash (or #!/usr/bin/env bash ) shebang line, and use bash v4 features. This'll fail on any system that has bash v3 (e.g. macOS, which has to use it for licensing reasons). Least portable: use a #!/bin/sh shebang and use bash extensions to the POSIX shell syntax. This will fail on any system that has something other than bash for /bin/sh (su...

Bash Shebang For Dummies?

Answer : If a script /path/to/foo begins with #!/bin/bash , then executing /path/to/foo arg1 arg2 is equivalent to executing /bin/bash /path/too/foo arg1 arg2 . If the shebang line is #!/bin/bash -ex , it is equivalent to executing /bin/bash -ex /path/too/foo arg1 arg2 . This feature is managed by the kernel. Note that you can portably have only one argument on the shebang line: some unices (such as Linux) only accept one argument, so that #!/bin/bash -e -x would lead to bash receiving the single five-character argument -e -x (a syntax error) rather than two arguments -e and -x . For the Bourne shell sh and derived shells such as POSIX sh, bash, ksh, and zsh: -e means that if any command fails (which it indicates by returning a nonzero status), the script will terminate immediately. -x causes the shell to print an execution trace. Other programs may understand these options but with different meanings. They are options passed to bash see help set for more info,...

Asynchronous Shell Exec In PHP

Answer : If it "doesn't care about the output", couldn't the exec to the script be called with the & to background the process? EDIT - incorporating what @AdamTheHut commented to this post, you can add this to a call to exec : " > /dev/null 2>/dev/null &" That will redirect both stdio (first > ) and stderr ( 2> ) to /dev/null and run in the background. There are other ways to do the same thing, but this is the simplest to read. An alternative to the above double-redirect: " &> /dev/null &" I used at for this, as it is really starting an independent process. <?php `echo "the command"|at now`; ?> To all Windows users: I found a good way to run an asynchronous PHP script (actually it works with almost everything). It's based on popen() and pclose() commands. And works well both on Windows and Unix. function execInBackground($cmd) { if (substr(php_uname(), 0, 7) =...

Alternative Console Host For Windows 7/Windows Server 2008

Answer : Below are some nice console-replacements products that are more user-friendly than cmd. As commented below, since Windows 7, all these shells are just an interface to conhost.exe, even powershell. For details, read What is conhost.exe and Why Is It Running. Therefore, the consoles below only replace the default visual interface to conhost which is the one exhibited by cmd, and are only useful when directly invoked as programs. They cannot be indirectly invoked, as when a console-executable such as diskpart is run, since this will invoke conhost, and conhost has its own I/O interface and API. Here is what Microsoft says in Windows 7 / Windows Server 2008 R2: Console Host : ConHost represents a permanent change in the way that console application I/O is handled. There is no registry key or group policy setting that can force Windows to revert back to “legacy mode” console behavior. The conclusion is that if you wish to replace the console in a deeper way t...

Can I Export A Variable To The Environment From A Bash Script Without Sourcing It?

Answer : Is there any way to access to the $VAR by just executing export.bash without sourcing it ? Quick answer: No. But there are several possible workarounds. The most obvious one, which you've already mentioned, is to use source or . to execute the script in the context of the calling shell: $ cat set-vars1.sh export FOO=BAR $ . set-vars1.sh $ echo $FOO BAR Another way is to have the script, rather than setting an environment variable, print commands that will set the environment variable: $ cat set-vars2.sh #!/bin/bash echo export FOO=BAR $ eval "$(./set-vars2.sh)" $ echo "$FOO" BAR A third approach is to have a script that sets your environment variable(s) internally and then invokes a specified command with that environment: $ cat set-vars3.sh #!/bin/bash export FOO=BAR exec "$@" $ ./set-vars3.sh printenv | grep FOO FOO=BAR This last approach can be quite useful, though it's inconvenient for interactive use sin...

Change Working Directory In Shell With A Python Script

Answer : Others have pointed out that you can't change the working directory of a parent from a child. But there is a way you can achieve your goal -- if you cd from a shell function, it can change the working dir. Add this to your ~/.bashrc: go() { cd "$(python /path/to/cd.py "$1")" } Your script should print the path to the directory that you want to change to. For example, this could be your cd.py: #!/usr/bin/python import sys, os.path if sys.argv[1] == 'tdi': print(os.path.expanduser('~/long/tedious/path/to/tdi')) elif sys.argv[1] == 'xyz': print(os.path.expanduser('~/long/tedious/path/to/xyz')) Then you can do: tdi@bayes:/home/$> go tdi tdi@bayes:/home/tdi$> go tdi That is not going to be possible. Your script runs in a sub-shell spawned by the parent shell where the command was issued. Any cd ing done in the sub-shell does not affect the parent shell.

Bash Script Runs Manually, But Fails On Crontab

Answer : The problem is probably that your $PATH is different in the manual environment from that under which crontab runs. Hence, which can't find your executables. To fix this, first print your path in the manual environment ( echo $PATH ), and then manually set up PATH at the top of the script you run in crontab. Or just refer to the programs by their full path. Edit: Add this near the top of your script, before all the which calls: export PATH="/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/mysql/bin:/opt/android-sdk-linux/tools:/opt/android-sdk-linux/platform-tools:~/usr/lib/jvm/jdk-6/bin" Another more generic way is to have cron run the user's bash logon process. In addition to the PATH, this will also pick up any LD_LIBRARY_PATH, LANG settings, other environment variables, etc. To do this, code your crontab entry like: 34 12 * * * bash -l /home/db-backup/mysqlbackup.sh My Issue was ...

Check If Database Exists In PostgreSQL Using Shell

Answer : Note/Update (2021): While this answer works , philosophically I agree with other comments that the right way to do this is to ask Postgres . Check whether the other answers that have psql -c or --command in them are a better fit for your use case (e.g. Nicholas Grilly's, Nathan Osman's, bruce's or Pedro's variant I use the following modification of Arturo's solution: psql -lqt | cut -d \| -f 1 | grep -qw <db_name> What it does psql -l outputs something like the following: List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+-----------+----------+------------+------------+----------------------- my_db | my_user | UTF8 | en_US.UTF8 | en_US.UTF8 | postgres | postgres | LATIN1 | en_US | en_US | template0 | postgres | LATIN1 | en_US | en_US | =c/postgres + | | |...
Answer : Resolving the operation not permitted error: sudo chmod u+x my_script.sh You created the file via: sudo vi my_script.sh # editing This means, the owner and group of the file is root. You are not allowed to change files of it by default. You need to change permission (chmod does it) or change the owner: sudo chown you:yourgroup my_script.sh This should do it. Save the trouble, without creating the file via sudo. You've created file my_script.sh with the root user as the owner (because you used sudo ), which is why you're not permitted to change the permissions as yourself . Thus, use sudo chmod u+x my_script.sh , but note that that will make the file only executable for the root user. To make the file executable by everyone, use sudo chmod a+x my_script.sh .

Bash: Double Equals Vs -eq

Answer : == is a bash -specific alias for = , which performs a string (lexical) comparison instead of the -eq numeric comparison. (It's backwards from Perl: the word-style operators are numeric, the symbolic ones lexical.) To elaborate on bollovan's answer... There is no >= or <= comparison operator for strings. But you could use them with the ((...)) arithmetic command to compare integers. You can also use the other string comparison operators ( == , != , < , > , but not = ) to compare integers if you use them inside ((...)) . Examples Both [[ 01 -eq 1 ]] and (( 01 == 1 )) do integer comparisons. Both are true. Both [[ 01 == 1 ]] and [ 01 = 1 ] do string comparisons. Both are false. Both (( 01 -eq 1 )) and (( 01 = 1 )) will return an error. Note: The double bracket syntax [[...]] and the double parentheses syntax ((...)) are not supported by all shells. If you want to do integer comparison you will better use (( )), where you can a...

Ansible Command Module Says That '|' Is Illegal Character

Answer : From the doc: command - Executes a command on a remote node The command module takes the command name followed by a list of space-delimited arguments. The given command will be executed on all selected nodes. It will not be processed through the shell, so variables like $HOME and operations like "<", ">", "|", and "&" will not work (use the shell module if you need these features). shell - Executes a commands in nodes The shell module takes the command name followed by a list of space-delimited arguments. It is almost exactly like the command module but runs the command through a shell (/bin/sh) on the remote node. Therefore you have to use shell: dpkg -l | grep python-apt . read about the command module in the Ansible documentation: It will not be processed through the shell, so .. operations like "<", ">", "|", and "&" will not work As it recommends, use t...

Capturing Groups From A Grep RegEx

Answer : If you're using Bash, you don't even have to use grep : files="*.jpg" regex="[0-9]+_([a-z]+)_[0-9a-z]*" for f in $files # unquoted in order to allow the glob to expand do if [[ $f =~ $regex ]] then name="${BASH_REMATCH[1]}" echo "${name}.jpg" # concatenate strings name="${name}.jpg" # same thing stored in a variable else echo "$f doesn't match" >&2 # this could get noisy if there are a lot of non-matching files fi done It's better to put the regex in a variable. Some patterns won't work if included literally. This uses =~ which is Bash's regex match operator. The results of the match are saved to an array called $BASH_REMATCH . The first capture group is stored in index 1, the second (if any) in index 2, etc. Index zero is the full match. You should be aware that without anchors, this regex (and the one using grep ) wi...