Mandalika's scratchpad [ Work blog @Oracle | My Music Compositions ]

Old Posts: 09.04  10.04  11.04  12.04  01.05  02.05  03.05  04.05  05.05  06.05  07.05  08.05  09.05  10.05  11.05  12.05  01.06  02.06  03.06  04.06  05.06  06.06  07.06  08.06  09.06  10.06  11.06  12.06  01.07  02.07  03.07  04.07  05.07  06.07  08.07  09.07  10.07  11.07  12.07  01.08  02.08  03.08  04.08  05.08  06.08  07.08  08.08  09.08  10.08  11.08  12.08  01.09  02.09  03.09  04.09  05.09  06.09  07.09  08.09  09.09  10.09  11.09  12.09  01.10  02.10  03.10  04.10  05.10  06.10  07.10  08.10  09.10  10.10  11.10  12.10  01.11  02.11  03.11  04.11  05.11  07.11  08.11  09.11  10.11  11.11  12.11  01.12  02.12  03.12  04.12  05.12  06.12  07.12  08.12  09.12  10.12  11.12  12.12  01.13  02.13  03.13  04.13  05.13  06.13  07.13  08.13  09.13  10.13  11.13  12.13  01.14  02.14  03.14  04.14  05.14  06.14  07.14  09.14  10.14  11.14  12.14  01.15  02.15  03.15  04.15  06.15  09.15  12.15  01.16  03.16  04.16  05.16  06.16  07.16  08.16  09.16  12.16  01.17  02.17  03.17  04.17  06.17  07.17  08.17  09.17  10.17  12.17  01.18  02.18  03.18  04.18  05.18  06.18  07.18  08.18  09.18  11.18  12.18  01.19  02.19  05.19  06.19  08.19  10.19  11.19  05.20  10.20  11.20  12.20 


Thursday, December 31, 2020
 
Perl: Handling Signals

Signals are used to notify processes of a synchronous or asynchronous event. When a signal is sent, operating system interrupts the flow of execution of target process to deliver the signal. If the process has a registered signal handler, the signal handler function will handle signals sent to the process. Otherwise, the default signal handler is executed. The default action for most signals is to terminate the process.

Almost all popular programming languages including Perl provide programming interfaces to send and receive signals. We will explore signal handling with a simple example in this blog post.

All Perl programs have access to a global variable %SIG hash that contains names or references of user-installed signal handlers. Each key in %SIG hash corresponds to a signal and associated value is the action to take when Perl runtime receives the corresponding signal. To ignore the signal, set the action to 'IGNORE'. To let the system perform the default action for the signal, set the action to 'DEFAULT'. To perform a desired action in response to a signal, write a signal handler with desired action(s) and set the action to execute that signal handler. To reiterate, a signal handler is just a function/subroutine including anonymous subroutines.

eg.,

$SIG{INT} = 'IGNORE' ;				# ignore signal INT
$SIG{INT} = 'DEFAULT';				# default signal handling for signal INT
$SIG{INT} =  sub { die "Caught sigint $!" };	# signal handler - anonymous subroutine
$SIG{INT}  = \&handle_sigint;			# signal handler - execute routine "handle_sigint"

Following sample code catches keyboard event Ctrl-C that generates SIGINT signal.

$ cat -n /var/tmp/sigint.pl
     1	#!/usr/bin/perl
     2	
     3	use strict;
     4	use warnings;
     5	
     6	sub handle_sigint {
     7	    print "Caught signal $! \n";
     8	}
     9	
    10	# install signal handler for SIGINT
    11	$SIG{INT}  = \&handle_sigint;
    12	
    13	print "Current time: " . localtime() . "\n";
    14	sleep(30);
    15	print "Time now: ". localtime() . "\n";

$ /var/tmp/sigint.pl
Current time: Thu Dec 31 16:35:00 2020
^CCaught signal Interrupted system call 
Time now: Thu Dec 31 16:35:07 2020

In this example, execution continued after the keyboard interrupt was handled. However note that not all signals allow execution to continue after the signal handler was executed.

Labels:




Saturday, November 28, 2020
 
pip error: Could not find an activated virtualenv (required)

Running pip commands encounter Could not find an activated virtualenv (required) error. Some of the options to get around this error are discussed in this blog post.

eg.,

# pip uninstall oci
ERROR: Could not find an activated virtualenv (required).

Try running the failed command by setting PIP_REQUIRE_VIRTUALENV to false. If the command succeeds and you don't want to encounter the same error in future, consider saving this environment variable in user's profile.

# PIP_REQUIRE_VIRTUALENV=false pip uninstall oci
Found existing installation: oci 2.18.0
Uninstalling oci-2.18.0:
  Would remove:
    /usr/lib/python2.7/site-packages/oci-2.18.0.dist-info/*
    /usr/lib/python2.7/site-packages/oci/*
Proceed (y/n)?

Another option is to run pip in isolated mode that ignores environment variables and user configuration.

# pip --isolated uninstall oci

Be aware that running in isolated mode won't ignore global configuration but only the user configuration. Therefore if there is a global configuration (say /etc/pip.conf) with a setting that forces virtual environment, --isolated option won't help.

eg.,

# pip --isolated uninstall oci
ERROR: Could not find an activated virtualenv (required).

In this case, examine global configuration by listing active configuration.

# pip config list
global.require-virtualenv='true'

Find out where the active configuration was loaded from by running pip with --verbose or -v (verbose) option.

# pip config list -v
For variant 'global', will try loading '/etc/xdg/pip/pip.conf'
For variant 'global', will try loading '/etc/pip.conf'
For variant 'user', will try loading '/root/.pip/pip.conf'
For variant 'user', will try loading '/root/.config/pip/pip.conf'
For variant 'site', will try loading '/usr/pip.conf'
global.require-virtualenv='true'

Finally edit global configuration to turn off the virtual environment requirement, and run the target pip command.

If editing the global configuration is not a viable option, consider ignoring global configuration tentatively while running target pip command(s).

eg.,

# PIP_CONFIG_FILE=/dev/null pip uninstall oci
Found existing installation: oci 2.18.0
Uninstalling oci-2.18.0:
  Would remove:
    /usr/lib/python2.7/site-packages/oci-2.18.0.dist-info/*
    /usr/lib/python2.7/site-packages/oci/*
Proceed (y/n)?

Labels:




Saturday, October 24, 2020
 
Blast from the Past : The Weekend Playlist #18 — New Wave 80s

Audio & Widget courtesy: Spotify

Old Playlists:

    #1    #8   #14 (50s, 60s and 70s)    |    #2    #3    #4    #5 (80s)    |    #6    #7    #9    #16 (90s)    |    #11    #12 (00s)    |    #13 (10s) |    #10 (Instrumental) |    #15 (Cirque Du Soleil)    |    #17 (MJ)

Labels:




Friday, May 08, 2020
 
Python Notes #1

Shuffling List Elements

Try shuffle method in random module.

shuffle() modifies the original sequence. In other words, shuffling happens in place and the function returns None.

To shuffle an immutable sequence -or- to save the shuffled sequence in a different object without disrupting original object holding the sequence, rely on random.sample() which returns a new shuffled list.

eg.,
>>> from random import shuffle, sample
>>> x = [1, 2, 3, 4, 5]
>>> y = shuffle(x)
>>> y
>>> x
[3, 2, 5, 4, 1]
>>> y = sample(x, len(x))
>>> y
[5, 3, 2, 1, 4]
>>> x
[3, 2, 5, 4, 1]

Checking all Imported Modules

Try sys.modules.keys()

eg.,
>>> import sys

>>> sys.modules.keys()
['copy_reg', 'sre_compile', '_sre', 'encodings', 'site', '__builtin__', 'sysconfig', '__main__', 'encodings.encodings', 'abc', 'posixpath', '_weakrefset', 
'errno', 'encodings.codecs', 'sre_constants', 're', '_abcoll', 'types', '_codecs', 'encodings.__builtin__', '_warnings', 'genericpath', 'stat', 'zipimport', 
'_sysconfigdata', 'warnings', 'UserDict', 'encodings.utf_8', 'sys', '_osx_support', 'codecs', 'readline', 'os.path', '_locale', 'signal', 'traceback', 
'linecache', 'posix', 'encodings.aliases', 'exceptions', 'sre_parse', 'os', '_weakref']

>>> import random

>>> sys.modules.keys()
['__future__', 'copy_reg', 'sre_compile', '_hashlib', '_sre', 'encodings', 'site', '__builtin__', 'sysconfig', '__main__', 'encodings.encodings', 'hashlib',
 'abc', 'posixpath', '_random', '_weakrefset', 'errno', 'binascii', 'encodings.codecs', 'sre_constants', 're', '_abcoll', 'types', '_codecs', 'encodings.__builtin__',
 '_warnings', 'math', 'genericpath', 'stat', 'zipimport', '_sysconfigdata', 'warnings', 'UserDict', 'encodings.utf_8', 'sys', '_osx_support', 'codecs', 'readline', 
'os.path', '_locale', 'signal', 'traceback', 'random', 'linecache', 'posix', 'encodings.aliases', 'exceptions', 'sre_parse', 'os', '_weakref']

Examining all Attributes in a Object

Try object.__dict__

__dict__ attribute contains all the attributes that describe the object. Helpful while debugging. It can be used to alter object's attributes too though I'm not sure if it is a recommended practice.

eg.,
>>> class A:
...     def __init__(self):
...             self.a = 100
...             self.b = 200
... 
>>> a = A()
>>> a.__dict__
{'a': 100, 'b': 200}

When dealing with complex objects, __dict__ may falter with errors such as TypeError: Object of type xxx is not JSON serializable.

Labels:




Saturday, November 30, 2019
 
Shell Scripting: Few Tidbits #2

Shell Scripting Tidbits: #1

Extracting the filename and extension from an absolute path

eg.,

Input: abspath="/var/tmp/localuserinfo.out"

Filename with extension:

$ basename ${abspath}
localuserinfo.out

Extension:

$ basename ${abspath##*.}
        -OR-
$ echo ${abspath##*.}
out

${variable##pattern} trims the longest match from the beginning of a string. Likewise ${variable#pattern} trims the shortest match from the beginning of a string.

Filename without extension:

$ basename ${abspath%.*}
localuserinfo

${variable%pattern} trims the shortest match from the end of a string. Similarly ${variable%%pattern} trims the longest match from the end of a string.

Ref:

Replacing commas with white space in a string

eg.,

Input: dummystr="Python,C,Java"

To replace all matches:

$ echo ${dummystr//,/ }
Python C Java

To replace only the first match:

$ echo ${dummystr/,/ }
Python C,Java

The difference is the extra '/' in pattern in first expression. If pattern begins with '/', all matches of pattern are replaced with string. Otherwise, only the first match is replaced.

Ref: Bash Reference Manual -> Shell Parameter Expansion -> ${parameter/pattern/string}

Sending array as argument to a shell function

Expand array before passing as argument to a function in a shell script. Sending the array name only passes the first element of the array.

Since $@ holds all arguments passed to the function, access the array argument with the help of $@ in the function definition. Using variables $1, $2, .., $n gives access to individual elements in the array.

eg.,
$ cat numbers.sh 

#!/bin/bash

# print_array() .. prints all elements as expected
function print_array() {
 int_array=("$@")
 for elem in "${int_array[@]}"
 do
  echo $elem
 done
}

# print_array2() .. prints only one element .. first one in the array
function print_array2() {
 int_array=($1)
 for elem in "${int_array[@]}"
 do
  echo $elem
 done
}

numbers=(1 2 3 4)
echo "Attempting to print numbers array .."
print_array ${numbers[@]}
echo
echo "Attempt #2 with a different function .."
print_array2 ${numbers[@]}
echo
echo "Attempt #3 with only the array name as argument to print_array function .."
# following call prints only the first element of the array
print_array ${numbers}

$ ./numbers.sh 
Attempting to print numbers array ..
1
2
3
4

Attempt #2 with a different function ..
1

Attempt #3 with only the array name as argument to print_array function ..
1

Labels:




Thursday, October 31, 2019
 
Shell Scripting: Few Tidbits #1

Length of a String Stored in a Variable

${#VARIABLE}

eg.,
$ FRUIT="Orange"

$ echo ${#FRUIT}
6

In bash, variables that store values are known as parameters.

Ref: Bash Reference Manual -> Shell Parameter Expansion -> ${#parameter}

Remove First n Characters from a String

${VARIABLE:n}

eg.,
$ PARAM="Quick Brown Fox"

$ echo ${PARAM:6}
Brown Fox

Remove Last n Characters from a String

${VARIABLE::-n}

eg.,
$ PARAM="Quick Brown Fox"

$ echo ${PARAM::-6}
Quick Bro

Convert a String to Upper Case

${VARIABLE} | tr '[:lower:]' '[:upper:]' eg.,

$ NAME='Giri Mandalika'

$ echo ${NAME} | tr '[:lower:]' '[:upper:]'
GIRI MANDALIKA

Convert a String to Lower Case

${VARIABLE} | tr '[:upper:]' '[:lower:]' eg.,

$ NAME='Giri Mandalika'

$ echo ${NAME} | tr '[:upper:]' '[:lower:]'
giri mandalika

Labels:




Saturday, August 10, 2019
 
Blast from the Past : The Weekend Playlist #17 — Michael Jackson Special

The King of Pop needs no special introduction so here goes.

This playlist features music from five different albums of MJ -- Off the Wall (1979), Thriller (1982; "Best-selling album" in Guinness World Records), Bad (1987), Dangerous (1991) and HIStory (1995).

Audio & Widget courtesy: Spotify

Old Playlists:

    #1    #8   #14 (50s, 60s and 70s)    |    #2    #3    #4    #5 (80s)    |    #6    #7    #9    #16 (90s)    |    #11    #12 (00s)    |    #13 (10s) |    #10 (Instrumental) |    #15 (Cirque Du Soleil)

Labels:




Saturday, June 29, 2019
 
Parsing JSON on Command Line or in a Shell Script

Couple of options:

1. If you do not have the flexibility of installing new utilities, or simply prefer working with existing tools, one option to consider is to make use of Python's JSON module.

One or more statements can be executed as a unit with the help of Python interpreter's -c option.

eg.,

Following example fetches Coordinated Universal Time with the help of an API published on web, and parses the returned JSON with the help of Python's JSON module to extract the current timestamp.

$ curl -s -X GET  -H "Content-Type: application/json" http://worldclockapi.com/api/json/utc/now | json_reformat
{
    "$id": "1",
    "currentDateTime": "2019-05-21T00:00Z",
    "utcOffset": "00:00:00",
    "isDayLightSavingsTime": false,
    "dayOfTheWeek": "Tuesday",
    "timeZoneName": "UTC",
    "currentFileTime": 132028704477448626,
    "ordinalDate": "2019-141",
    "serviceResponse": null
}

% UTC_DATA=$(curl -s -X GET  -H "Content-Type: application/json" http://worldclockapi.com/api/json/utc/now)
% CURTIMESTAMP=$(python -c "import sys, json; props = json.loads('$UTC_DATA'); print props['currentDateTime']")

% echo $CURTIMESTAMP
2019-05-21T00:01Z

Here's another example that extracts the value of more than one attribute in a shell.

UTC_ATTR=$(python -c "import sys, json; props = json.loads('$UTC_DATA'); print 'TIMESTAMP={0} TZ={1} DAY={2} DayLightSavings={3}' \
   .format(props['currentDateTime'], props['timeZoneName'], props['dayOfTheWeek'], props['isDayLightSavingsTime'])")

UTC_ATTR_ARR=($UTC_ATTR)

$ for ATTR in "${UTC_ATTR_ARR[@]}"
> do
>  echo $ATTR
> done
TIMESTAMP=2019-05-21T00:01Z
TZ=UTC
DAY=Tuesday
DayLightSavings=False
To be continued ..

Labels:




Saturday, May 25, 2019
 
Blast from the Past : The Weekend Playlist #16

Audio & Widget courtesy: Spotify

Old playlists:

    #1    #8   #14 (50s, 60s and 70s)    |    #2    #3    #4    #5 (80s)    |    #6    #7    #9 (90s)    |    #11    #12 (00s)    |    #13 (10s) |    #10 (Instrumental) |    #15 (Cirque Du Soleil)

Labels:




Thursday, February 28, 2019
 
Perl: Enabling Features

By default new features are not enabled in Perl mainly to retain backward compatibility. Starting with release 5.10, latest features have to be enabled explicitly before using them. Here are a few ways to enable Perl features.

  1. Enable new features with the help of -E switch.

    • Introduced in v5.10, -E is similar to -e switch except that -E also enables all latest features. In other words, -E switch on the Perl command line enables the feature bundle for that version of Perl in the main compilation unit. (see #4 below for enabling feature bundles explicitly).

    eg.,

    % perl -e 'print $^V;'
    v5.16.3
    
    % perl -e "print q(Hello)"
    Hello% ⏎
    % perl -E "print q(Hello)"
    Hello% ⏎
    % perl -e "say q(Hello)"
    syntax error at -e line 1, near "say q(Hello)"
    Execution of -e aborted due to compilation errors.
    % perl -E "say q(Hello)"
    Hello
    %
    
  2. Enable one or more features selectively with the help of use feature pragma.

    • use feature pragma minimizes the risk of breaking existing programs as the specified feature will only be enabled within the scope of the pragma.

    eg.,

    % cat -n enable_say.pl
         1  #!/bin/perl
         2  say("Hello")
    
    % ./enable_say.pl
    Undefined subroutine &main::say called at ./enable_say.pl line 2.
    
    % cat -n enable_say.pl
         1  #!/bin/perl
         2  use feature say;
         3  say("Hello")
    
    % ./enable_say.pl
    Hello
    

    To enable multiple features, spearate each one with spaces. eg., use feature qw(say state switch unicode_strings).

  3. Enable all features available in the requested version with the help of use <VERSION> directive.

    • use <VERSION> disables any features not in the requested version's feature bundle. (see #4 below for enabling feature bundles explicitly). This is useful to check the current Perl version before using library modules that won't work with older versions of Perl.

    eg.,

    % cat -n enable_say.pl
         1  #!/bin/perl
         2  say("Hello")
    
    % ./enable_say.pl
    Undefined subroutine &main::say called at ./enable_say.pl line 2.
    
    % cat -n enable_say.pl
         1  #!/bin/perl
         2  use v5.10;
         3  say("Hello")
    
    % ./enable_say.pl
    Hello
    
  4. Similar to use <VERSION> directive, feature bundles help load multiple features together. Any feature bundle can be enabled with the help of use feature ":<FEATURE_BUNDLE>" directive.

    The colon that prefixes the feature bundle differentiates the bundle from an actual feature.

    eg.,

    To enable say, state, switch, unicode_strings, unicode_eval, evalbytes, current_sub and fc features, enable feature bundle 5.16 as shown below.

    #!/bin/perl
    ..
    use feature ":5.16";
    ..
    

    Perl features available in various feature bundles are listed here.

Credit: various sources

Labels:





2004-2019 

This page is powered by Blogger. Isn't yours?