Tag Info

Hot answers tagged

43

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 ...


20

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 ...


20

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 ...


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 ...


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

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 ...


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

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.


8

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 ...


8

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

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

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

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.


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

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 ...


6

@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 ...


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

~/.profile is only read by login shells. ~/.kshrc is only executed for interactive shells. Solaris's env supports the syntax (now deprecated, but retained in Solaris, which takes backward compatibility seriously) env - /path/to/command to run /path/to/command in an empty environment. So env - /usr/bin/ksh -c /path/to/script will run the script in an empty ...


6

BEGIN patterns are executed before any input is read, so consequently none of the variables that refer to input, like NR, fields like $0..., will be defined in any of the BEGIN blocks. Your second approach is correct and much better.¹ From the POSIX awk spec (emphasis mine): The awk utility shall recognize two special patterns, BEGIN and END. Each ...


6

if you want a child process, spawned from your script, to use a pre-defined shell function you need to export it with export -f <function> NOTE: export -f is bash specific since only a shell can run shell functions: find / -exec /bin/bash -c 'function "{}"' \; EDIT: essentially your script should resemble this: #!/bin/bash function foo() { do ...


6

Old school — you could use dd: dd if=A_FILE bs=1c skip=3 The input file is A_FILE, the block size is 1 character (byte), skip the first 3 'blocks' (bytes). There are other ways too: sed '1s/^...//' A_FILE This works if there are 3 or more characters on the first line. tail -c +4 A_FILE And you could use Perl, Python and so on too.


6

This will accomplish what you ask: awk -F';' '{print $1 ";" $2 ";" $3;}' <input >output The awk utility is well designed for this task. It can easily cut up individual lines into fields, then manipulate them based on that. The -F';' argument tells awk to use ; as the field separator. The quotes are necessary because the shell would interpret ; as a ...


6

This is what I use in my .profile to check for various shells on the systems I work on. It doesn't make fine distinctions between ksh88 and ksh93, but it has never failed me. Note that it doesn't require a single fork or pipe. # Determine what (Bourne compatible) shell we are running under. Put the result # in $PROFILE_SHELL (not $SHELL) so further code ...


5

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 ...


5

Unfortunately AIX su doesn't have the --shell parameter available on other platforms. Do you have any user defined on the system without Korn shell? Use the serial console and boot into maintenance mode, hopefully it's shell comes up. Unless prepared before hand network booting likely to be too troublesome. Otherwise you need someone with physical access ...


5

It is typical for programs to force the "some_string" part to be the last argument so that .abc.ksh "some_string" -a "sample text" is an error. If you do this, then after parsing the options, $OPTIND holds the index to the last argument (the "some_string" part). If that is not acceptable, then you can check at the beginning (before you enter the while to ...


5

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


5

\t on the right hand side of a sed expression is not portable. Here are some possible solutions: POSIX shell Bear in mind that since many shells store their strings internally as cstrings, if the input contains the null character (\0), it may cause the line to end prematurely. echo "something" | while IFS= read -r line; do printf '\t%s\n' "$line"; done ...



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