Hot answers tagged

70

I can reproduce your behaviour if I alias fi: $ alias fi=: + alias fi=: $ . ./test + . ./test ++ set -x bash: ./test: line 6: syntax error: unexpected end of file It works when you execute it but fails when you source it because aliases are not available in non-interactive shells (the type of shell that runs shell scripts). As explained in the bash manual:...


6

No. By the time a shebang comes into play, you have already lost. A shebang is applied when a process is exec()'d and typically that happens after forking, so you're already in a separate process. It's not the shell that reads the shebang, it's the kernel.


5

$$ is the process ID of the current shell instance. So in your case the number, 23019, is the PID of that instance of bash. The following should give you a better idea: ps -p $$


5

make test || true e.g. #!/bin/sh set -e echo hello make test || true echo done Will result in hello make: *** No rule to make target `test'. Stop. done In this case the failure was a missing rule (no Makefile :-)) but we can see the script continues.


5

You can do this with an awk command most easily: your-command | awk -F\" -v OFS=. -v ORS=' ' '{print $2, $4, $6, $8}' To set it as a variable, use command substitution: myVariable="$(your-command | awk -F\" -v OFS=. -v ORS=' ' '{print $2, $4, $6, $8}')" -F sets the input field separator (which is by default any whitespace) to a custom value; in this ...


4

I would use perl to slurp the file into memory and remove any leading whitespace if and only if the first non-whitespace character in the file is a shebang: perl -i.bak -0pe 's/^\s+(?=#!)//' file Or, for many files: for f in ./*; do perl -i.bak -0pe 's/^\s+(?=#!)//' "$f"; done The (?=#!) is a positive lookahead, so the substitution operator will only ...


4

A standard UNIX shell will do something called globbing; this uses special characters to mean, for example, one character (?) or any number of characters (*). To use your example, you could run (where the initial $ represents your command prompt and not something you'd type): $ command /home/mydir/*.dat > /home/outputdir/output.dat Your shell will ...


3

You can do it without the grep: df --output=target,size /mnt/xyz | awk ' NR==2 { print $2 } ' df accepts as argument the mount point; you can tell to awk too to print both the second line only (NR==2) , and the 2nd argument, $2. Or better yet, cut the target as you are not outputting it, and it becomes: df --output=size /mnt/xyz | awk ' NR==2 ' When I ...


3

Indeed, pssh sounds like the better solution. If you must use parallel it should be fairly simple: pipe the hostnames one per line into a single command that uses {} as a placehold. Eg: consul members | ... awk {'print $2'} | cut -d ":" -f1 | parallel -j 10 sshpass -p "$PASSWORD" ssh -oStrictHostKeyChecking=no -q root@{} "hostname && yum clean all &...


3

There's no way to tell for sure whether a file has been renamed. When a file is renamed, its inode number doesn't change. (This may not be true for “exotic” filesystems, such as network filesystems, but it's true for all “native” Unix filesystems.) However the converse is not true: if a file is deleted, a new file may be created with the same inode number. ...


2

There are a couple of mistakes in your script. The first line should point to your csh executable, which you've identified in the comments as /usr/bin/csh (rather than /bin/csh). The if line is missing the $ to identify speed as a variable. Here is a corrected script #!/usr/bin/csh # Over speed indicator # echo -n "How fast are you going?" set speed = $< ...


2

Use eval on your final line, and make sure the parent shell doesn't eat the $: #!/bin/bash export FOO=bar export BAR=baz eval "$@" run like so: wouter@gangtai:~$ ./foo.sh echo '$BAR' baz For more information, see help eval.


2

set -e can be flipped with set +e. #!/bin/sh set -e configure && make set +e make test ...


2

As user @muru says, it's not possible to do because you have already left the shell session behind when you get to the #!-line. However, depending on what your shell files do, there might be another solution. I'm guessing that they set environment variables that you use for some project. Let's call a project subtool (because that's a project I have). Then ...


2

I think this does what you want; it accepts an awk variable named "factor" that is can easily be set to whatever you want: awk -v factor=8.06573 '{printf "%2.9f %2.9f\n", $1 * factor, $2 * factor}' With the given input, it outputs: 34.193855762 35.948152037 34.220472671 33.078365303 34.585043667 33.260650801 33.961562738 36.169959612 34.176917729 33....


2

This is occurring because the output for v3.3.6 was going to stderr, not stdout. Apparently, prior to v3.4.0 the output from python --version is sent to stderr, whereas in v3.4.0 and later this output is sent to stdout. Redirection of both stdout and stderr to the output file works just fine: python --version >> $fname 2>&1


2

You were on the right track to use awk. You should write a script that reads your logs, and outputs with the fields separated with tabs¹. Then use the column command to re-align the columns: extract.awk²: BEGIN {OFS="\t"; print "Timestamp\tEmailTo:\tEmailFrom:\tIPAddress:\tErrorCodes:"} {print $1, $6, $7, $NF, $(NF-5)} Then run it with this command: awk ...


2

That's quite simple: sed -i "s/\[ \]/[$(cat output.txt | xargs)]/" input.txt


2

In your loop, there is a short window of time between the "stty echo" at the end of the loop and the "stty -echo" at the next iteration. Keyboard input received during this window will be echoed, even though no read command is waiting for it. If you don't want echoes, don't call "stty echo" 😉


1

You can do that with bash itself, using command substitution and then parameter expansion. First take the output of the command in a variable by using command substitution $(), and then use parameter expansion to replace all newlines with spaces ${variable//$'\n'/ }: $ myVariable=$(grep "type" /root/myFile | cut-d'=' -f2) $ myVariable=${myVariable//$'\n'/ ...


1

myVariable=`grep "type" /root/myFile | cut-d'=' -f2` What is between back-ticks (`) is run and the output is assigned to myVariable. If your current output is separated by line feeds (\n), then you may want to replace them with spaces with tr such as: myVariable=`grep "type" /root/myFile | cut-d'=' -f2`|tr '\n' ' '` Note: Some people prefer using the $...


1

Maybe you are looking for a "chroot jail for ssh", if the users require a terminal. Otherwise, if you just need they can access to their homes, configure sshd to jail stfp users in their homes: add to sshd_config: Match group myGroup //Also can match users ChrootDirectory %h ForceCommand internal-sftp -u 0007 AllowTcpForwarding no ...


1

Use pssh with ssh host key authentication it's better first, on the local box, as the user to connect with, do ssh-keygen to create a public key then use ssh-copy-id to copy that public key to all the remote servers. then do sometinhg like: pssh -h <(consul members | grep awk {'print $2'} | cut -d ":" -f1) -o /tmp/update-consul-servers -i "yum clean ...


1

To copy the oldest file to ../complete: cp -v "$(find ../in -maxdepth 1 -type f -printf '%T@ %p\0' | sort -zn | \ sed -zn '1s/[0-9,\.]\+ //p')" ../complete To copy the all except the oldest to ../error: find ../in -maxdepth 1 -type f -printf '%T@ %p\0' | sort -zn | \ sed -zn '2,$s/[0-9,\.]\+ //p' | xargs -0 cp -vt ../error Explanation: find -...


1

From Advanced Bash-Scripting Guide: $$ is the process ID (PID) of the script itself. $BASHPID is the process ID of the current instance of Bash. This is not the same as the $$ variable, but it often gives the same result.


1

If you are intent on scraping the hash off the page, then something like this will work. It's the sort of one-liner I write for one-off use, because it's likely to break as soon as the layout changes: hashsum=$(curl http://php.net/downloads.php | grep -A1 -F ">php-${pkgver}.tar.xz<" | sed 1d | tr '>' '<' | cut -d '<' -f3 ) To ...


1

you can give multiple instruction in one shot of sed, for example: sed 's/\t/ /g;/^ *$/d;s/^#/NODIESE/' testfile this single line replace tab with space delete line that start with empty stuff (or empty line) replace Dash at start with the word NODIESE so your test file is processed only once and you launch sed only one time.


1

You could get your production_env.sh to test for no args (or some special single arg like -i) and then read a single line (with -e to allow input editing) and execute it. Eg change its last line to: if [ $# = 0 -a -t 0 ] then read -p 'prod> ' -e cmd bash -c "$cmd" else "$@" fi


1

The answer really depends on what tool you're trying to use. Some are designed to accept multiple files as parameters, which can be done with: /path/to/some/tool file1 /path/to/file2 /path/to/lotsafiles/* Others are designed to only accept one file as a parameter, and so will have to be repeatedly invoked with each file you want to address, which would ...



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