Tag Info

Hot answers tagged

83

Using & causes the program to run in the background, so you'll get a new shell prompt instead of blocking until the program ends. nohup and disown are largely unrelated; they suppress SIGHUP (hangup) signals so the program isn't automatically killed when the controlling terminal is closed. nohup does this when the job first begins. If you don't nohup a ...


27

The single bracket [ is actually an alias for the test command, it's not syntax. One of the downsides (of many) of the single bracket is that if one or more of the operands it is trying to evaluate return an empty string, it will complain that it was expecting two operands (binary). This is why you see people do [ x$foo = x$blah ], the x guarantees that ...


22

Maybe not what you're asking for, but this should work to some extent to identify the interpreter currently interpreting it for a few like Thomson (osh), Bourne, Bourne-again, Korn, Z, (T)C, Policy-compliant Ordinary, Yet Another, rc, akanga, es shells, wish, tclsh, expect, perl, python, ruby, php, JavaScript (SpiderMonkey shell and JSPL at least), MS/Wine ...


16

When "SOMEPATTERN" starts or may start (for instance if it's a variable like "$PATTERN" which you don't have full control on) with a - (dash) character. Also with GNU grep (unless $POSIXLY_CORRECT is on), it's useful if other arguments (file names) may start with -. Alternatively, you can do grep -e -SOMEPATTERN- -- file1 file2 -xxx- -- marks the end of ...


13

It's showing the contents of the special variable $@, in Bash. It contains all the command line arguments, and this command is taking all the arguments from the second one on and storing them in a variable, variable. Example Here's an exampe script. #!/bin/bash echo ${@:2} variable=${@:3} echo $variable Example run: ./ex.bash 1 2 3 4 5 2 3 4 5 3 4 5 ...


12

AProgrammer's suggestion of using xargs is often best, but another option is to use redirection into a while loop, which allows additional commands to be made and variables to be set: while read -r dir; do mkdir $dir; done < myfile An example of a more complicated structure would be: now=`date +%Y%m%d.%H%M%S` while read -r dir; do ...


12

The [ command is an ordinary command. Although most shells provide it as a built-in for efficiency, it obeys the shell's normal syntactic rules. [ is exactly equivalent to test, except that [ requires a ] as its last argument and test doesn't. The double brackets [[ … ]] are special syntax. They were introduced in ksh (several years after [) because [ can ...


12

The reason file.txt is empty after that command is the order in which the shell does things. The first thing that happens with that line is the redirection. The file "file.txt" is opened and truncated to 0 bytes. After that the sed command runs, but at the point the file is already empty. There are a few options, most involve writing to a temporary file. ...


11

You should reduce the columns output by ps to the minimum, i.e. request only the username here - this simplifies further processing. For example: $ ps -eo user= will print the owner of all the currently running processes (= suppresses the header). An easy way to get the counts for each user: $ ps -eo user= | sort | uniq -c 1 dovecot 1 messagebus ...


10

I usually use the -exec utility. Like this: find . -type f -exec du -a {} + I tried it both on bash and ksh with GNU find. I never tried AIX, but I'm sure your version of find has some -exec syntax. The following snippet sorts the list, largest first: find . -type f -exec du -a {} + | sort -n -r | less


10

At least in bash, as long as there are no filenames containing spaces and newlines, this: mkdir $(< myfile) works. So we have a useless use of for, xargs too. < does not start a new process in bash, in contrast to cat, but I don't know for ksh.


10

From help let: Exit Status: If the last ARG evaluates to 0, let returns 1; let returns 0 otherwise.. Since var++ is post-increment, I guess the last argument does evaluate to zero. Subtle... A perhaps clearer illustration: $ let x=-1 ; echo x=$x \$?=$? x=-1 $?=0 $ let x=0 ; echo x=$x \$?=$? x=0 $?=1 $ let x=1 ; echo x=$x \$?=$? x=1 $?=0 $ let x=2 ; echo ...


10

That's a ksh feature also found in bash and recent versions of zsh. In ksh and bash, you can access several elements of an array by using the ${array[@]:first:length} syntax, which expands to up to length (or all if length is omitted) elements of the array array (in the list of elements of the array sorted numerically on the indexes), starting with the ...


9

When they are not quoted, $* and $@ are the same. You shouldn't use either of these, because they can break unexpectedly as soon as you have arguments containing spaces or wildcards. "$*" expands to a single word "$1c$2c...". Usually c is a space, but it's actually the first character of IFS, so it can be anything you choose. The only good use I've ...


8

Your code looks like an entirely justified example of using tempfiles to me. I'd stay: stick with this approach. The only thing that really needs to be changed is the way you create the tempfile. Use something like TMP=$(tempfile) or TMP=$(mktemp) or at least TMP=/tmp/myscript_$$ This way you won't let the name be easily predicted (security) and ...


8

First of all, you should use straight single quotes ('), not the inclined ones (`). The awk inline script could be as follow: ls -lrt | awk '{ total += $5 }; END { print total }' so, no need to initialize total (awk initializes it to zero), and no need to loop, awk already executes the script on every line of input.


8

You can do this sort of thing with eval, built-in to many fine shells, including ksh: #!/usr/bin/ksh set $(iostat) myvar=6 eval "echo \$$myvar" The trick is to double-quote the string you feed to eval so that $myvar gets substituted with "6", and to backslash the outer dollar-sign, so that eval gets a string "$6". I got "%user" for the output, but I ...


8

When the pattern starts with a dash, otherwise grep will think it is an option. Say, you are looking for "-a" in a text: grep -a file.txt grep will then try to find the pattern "file.txt" in the standard input, using the option -a. Therefore, you need to do grep -- -a file.txt


7

@enzotib has already pointed out what your syntax error is - I'm going to go off on a little tangent. Summing a column of numbers is one of those things that keeps popping up. I've ended up with this shell function: sumcol() { awk "{sum+=\$$1} END {print sum}" } With this, your solution becomes: ls -lrt | sumcol 5 That will sum the numbers in ...


7

If you do $ ksh -n 'if [[ 1 -eq 1 ]]; then echo hi; fi' you get the message ksh: warning: line 1: -eq within [[...]] obsolete, use ((...)) as you've seen. Now try this: $ ksh -n 'if (( 1 -eq 1 )); then echo hi; fi' ksh: 1 -eq 1 : arithmetic syntax error This works: $ ksh -n 'if (( 1 == 1 )); then echo hi; fi' Remember that the first message is ...


7

I was under the impression that pdksh was not POSIX compliant, and with the release of open source AT&T KSH, there was significant movement from pdksh to ksh. Just my $0.02 AT&T ksh is licensed by the Eclipse Public License 1.0 (EPL-1.0).


7

The code you provided will give the same result. To understand it better, try this: foo () { for i in "$*"; do echo "$i" done } bar () { for i in "$@"; do echo "$i" done } The output should now be different. Here's what I get: $ foo() 1 2 3 4 1 2 3 4 $ bar() 1 2 3 4 1 2 3 4 This worked for me on bash. As far as I know, ...


7

Syntax error: use no quotes inside arithmetic evaluation. Logic error: you are mixing STDOUT and return values. Either pass values as STDOUT: function factorial { (( $1 )) && echo $(( $1 * $( factorial $(( $1 - 1 )) ) )) || echo 1 } factorial 5 Or return them: function factorial { (( $1 )) || return 1 factorial $(( $1 - ...


7

A function is local to a shell, so you'd need find -exec to spawn a shell and have that function defined in that shell before being able to use it. Something like: find ... -exec ksh -c ' function foo { echo blan: "$@" } foo "$@"' ksh {} + Some versions of some implementations of ksh on some systems allow to export functions in the environment ...


7

You should use it this way: ls -l | awk -v d="$Date" '$0 ~ d {print $NF}' Explanation is here But may be it's better to use find in your script. find . -maxdepth 1 -type f -daystart -ctime -`date "+%d"` If you have classic awk instead of gawk: find * -prune -type f -cmin -`date '+%d %H %M' | awk '{print ($1*24+$2)*60+$3}'`


7

The LINE parameter isn't quoted so wordsplitting happens upon the expansion of $LINE in echo $LINE and by the time awk receives any input, you have 7 words(as seen by the shell) all separated by a single space. You want echo to output it as one word(again, as seen by the shell) so the whitespace in your line isn't mangled before awk can process it. That is ...


7

With awk: awk '{ print $(NF-1) }' NF is the number of fields -- all that happens here is that one is subtracted from the total field length to get the penultimate field. With perl: perl -lane 'print $F[-2]' An array containing the fields is created as @F (that's what -a does), and we get the value of the second last field (with index -2). Using sed ...


6

From the ksh faq: Q1. How do I get separate history files for shell? A1. ksh uses a shared history file for all shells that use the same history file name. This means that commands entered in one window will be seen by shells in other windows. To get separate windows, the HISTFILE variable needs to be set to different ...


6

Looks like a simple mistake: ${ENDOFLINE%$} strips a $ at the end of $ENDOFLINE, but what you want to do is use $ENDOFLINE literally and have a $ after it to indicate the end of the line. if [[ ("$LINE" =~ "^#;") && (( ("$LINE" =~ "${ENDOFLINE}$") )) ]]; This works in zsh but not in ksh or bash. Bash requires the regexp $ to be unquoted ...


6

If you want to parallelize on a machine with multiple cores, you can just use (GNU) xargs, e.g.: echo seq_[0-9][0-9].gz | xargs -n 1 -P 16 ./crunching Meaning: xargs starts up to 16 processes in parallel of ./crunching using 1 token from stdin for each process. You can also use split in combination with xargs. Or you can create a simple Makefile for Job ...



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