Shell Shift Procedure - What Is This

The advantage of shift in shell script over reassign value straightforward

shift will remove the first positional argument, and shift every other argument left one.

For example, let's consider the following:

#!/bin/bash
echo "$@"
shift
echo "$@"
shift
echo "$@"

Given that echo "$@" will print all of the arguments, if you were to run this, then the following would happen:

./test.bash 1 2 3 4 5

echo "$@" # prints 1 2 3 4 5
shift # Removes 1 and shifts everything else along
echo "$@" # prints 2 3 4 5
shift # shifting again
echo "$@" # prints 3 4 5

In your example, the script is parsing all of the flags. -i and -h are just switches and handle no following arguments. However, -f requires a filename.

The second shift will process the flag, shift the arguments, and then process them again. Therefore you can have ./program.bash -i -f filename. The -i will be shifted by the second shift, and then the filename will be processed on the next loop.

If you were to run ./program.bash -f filename -i, then the filename would need to be shifted along with the -f. Therefore, on the case block for -f there is an extra shift. In this example, -f would be shifted inside the case block, and then filename would be shifted by the second shift. Then the loop would run again to process any further flags.

As the while loop is [[ -n $1 ]], the loop will run until there are no more arguments.

Handling named arguments in bash

you mean something like this:

#!/bin/bash

deploy=false
uglify=false

while (( $# >= 1 )); do
case $1 in
--deploy) deploy=true;;
--uglify) uglify=true;;
*) break;
esac;
shift
done

echo "deploy: $deploy"
echo "uglify: $uglify"

examples

$ ./scriptname
deploy: false
uglify: false

$ ./scriptname --deploy
deploy: true
uglify: false

$ ./scriptname --uglily
deploy: false
uglify: true

$ ./scriptname --depoly --uglily
deploy: true
uglify: true

How to get arguments with flags in Bash

This is the idiom I usually use:

while test $# -gt 0; do
case "$1" in
-h|--help)
echo "$package - attempt to capture frames"
echo " "
echo "$package [options] application [arguments]"
echo " "
echo "options:"
echo "-h, --help show brief help"
echo "-a, --action=ACTION specify an action to use"
echo "-o, --output-dir=DIR specify a directory to store output in"
exit 0
;;
-a)
shift
if test $# -gt 0; then
export PROCESS=$1
else
echo "no process specified"
exit 1
fi
shift
;;
--action*)
export PROCESS=`echo $1 | sed -e 's/^[^=]*=//g'`
shift
;;
-o)
shift
if test $# -gt 0; then
export OUTPUT=$1
else
echo "no output dir specified"
exit 1
fi
shift
;;
--output-dir*)
export OUTPUT=`echo $1 | sed -e 's/^[^=]*=//g'`
shift
;;
*)
break
;;
esac
done

Key points are:

  • $# is the number of arguments
  • while loop looks at all the arguments supplied, matching on their values inside a case statement
  • shift takes the first one away. You can shift multiple times inside of a case statement to take multiple values.

Capture the output of Perl's 'system()'

That's what backticks are for. From perldoc perlfaq8:

Why can't I get the output of a command with system()?

You're confusing the purpose of system() and backticks (``). system()
runs a command and returns exit status information (as a 16 bit value:
the low 7 bits are the signal the process died from, if any, and the
high 8 bits are the actual exit value). Backticks (``) run a command
and return what it sent to STDOUT.

my $exit_status   = system("mail-users");
my $output_string = `ls`;

See perldoc perlop for more details.

Unable to copy/paste in MinGW shell

Right-click on the title bar of the command window and select 'Properties', then on the 'Options' tab tick the box for the 'QuickEdit mode', then click 'Ok'.

After that you can paste text from the clipboard using the right mouse-button, highlight text while holding down the left mouse-button and copy selected text using the ENTER key.

This procedure works on Windows 7/8, not Windows 10.

Converting HeapSort and ShellSort from C to Pascal

Transferring comments into an answer.

In the Shell sort, the C loop is:

for (i = shift; i < n; i += 1){

and the Pascal loop is

For i:=shift to n Do

The Pascal loop is looping once too often; it needs to be:

For i := shift to n-1 Do

assuming expressions are allowed in loop limits — if not, you need an extra variable, roughly like this:

var ub: integer;
ub := n - 1;

For i := shift to ub Do

The C for loop is much more general and flexible than the Pascal for loop.

In the Heap sort, the C loop is:

do { … } while (N > 1);

and you've translated that to

repeat … until n > 1;

The terminating condition is wrong; until is equivalent to while not, so you need:

repeat … until n <= 1;

I've by no means scrutinized the whole of the Pascal code — and I have no Pascal compiler to test with — so there could be other issues to be resolved still, but these two should get you going. (Make sure you've checked all the occurrences of for and repeat … until for the problems outlined here.)



Related Topics



Leave a reply



Submit