Tuesday, 23 June 2015

Use "-alt" to instruct the "ls" command to list folder contents by modified date/time in descending order

Oftentimes I'm in "Git Bash" console, Cygwin's full-blown Bash, or suchlike console using the "ls" command with the "-l" option to get output like this for example:

$ ls -l
total 12
drwxr-xr-x    4 Mark New Administ        0 Apr 16 14:18 Atlassian
drwxr-xr-x   50 Mark New Administ    12288 Jun 22 17:32 GphcSvnRepos
drwxr-xr-x   18 Mark New Administ     4096 May 22 14:12 MyGphc
drwxr-xr-x   13 Mark New Administ     4096 Jun  4 17:00 gphc
drwxr-xr-x   18 Mark New Administ     4096 May 15 08:42 nDumbster
drwxr-xr-x    5 Mark New Administ        0 Jun 10 10:21 tmp

...you can include the year "--full-time":

$ ls -alt --full-time
total 18
drwxr-xr-x   50 Mark New Administ    12288 Mon Jun 22 17:32:08 2015 GphcSvnRepos
drwxr-xr-x    1 Mark New Administ     8192 Mon Jun 22 16:11:47 2015 ..
drwxr-xr-x    1 Mark New Administ     4096 Mon Jun 22 16:11:38 2015 .
drwxr-xr-x    5 Mark New Administ        0 Wed Jun 10 10:21:34 2015 tmp
drwxr-xr-x   13 Mark New Administ     4096 Thu Jun 04 17:00:29 2015 gphc
drwxr-xr-x   18 Mark New Administ     4096 Fri May 22 14:12:11 2015 MyGphc
drwxr-xr-x   18 Mark New Administ     4096 Fri May 15 08:42:46 2015 nDumbster
drwxr-xr-x    4 Mark New Administ        0 Thu Apr 16 14:18:45 2015 Atlassian

...but I also want to sort by date in descending order like I often do in Windows Explorer:


Using the "ls" command, use arguments "-alt". This is from ls's help:

$ ls --help
Usage: ls [OPTION]... [FILE]...
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuSUX nor --sort.

  -a, --all                  do not hide entries starting with .
  -l                         use a long listing format
  -t                         sort by modification time

$ ls -alt
total 18
drwxr-xr-x   50 Mark New Administ    12288 Jun 22 17:32 GphcSvnRepos
drwxr-xr-x    1 Mark New Administ     8192 Jun 22 16:11 ..
drwxr-xr-x    1 Mark New Administ     4096 Jun 22 16:11 .
drwxr-xr-x    5 Mark New Administ        0 Jun 10 10:21 tmp
drwxr-xr-x   13 Mark New Administ     4096 Jun  4 17:00 gphc
drwxr-xr-x   18 Mark New Administ     4096 May 22 14:12 MyGphc
drwxr-xr-x   18 Mark New Administ     4096 May 15 08:42 nDumbster
drwxr-xr-x    4 Mark New Administ        0 Apr 16 14:18 Atlassian

To make it easier and so you don't have to remember the options, create a command shortcut (alias):

Edit (create one if it's not already there) your personal Bash customisation file $HOME/.bash_profile, eg:

$ cat ~/.bash_profile
alias hg='history | grep -i'
alias lst='ls -alt'

As you can see, I've included my most used & time saving alias "hg" to search my recent command history (saved across sessions unlike Windows 'cmd' console).  Remember you can then use "!" to tell Bash to re-run the numbered command from history's output to save re-typing it over and over, eg:

$ hg checkout
  333  git checkout -b crm
  350  git checkout -b crm
  353  git checkout -b crm
  361  git checkout origin/master
  363  git checkout origin
  365  git checkout master
  488  git checkout -b crm
  489  git checkout crm
  493  git checkout master
  565  hg checkout

$ !363
git checkout origin

As you can see Bash expands it to the full command and echoes it to the screen whilst running it.

You can also use 'beginning with abc...' eg:

$ !git check
git checkout origin check

I hope this is useful to someone in the world at some point in ever enduring time!






Friday, 11 April 2014

ASP.NET Restart on External Config File Changes - restartOnExternalChanges=”true” & AppSettings

If using external ASP.NET config files and you want your app to restart automatically when they're updated...

Common structure:
~/config/system.diagnostics.config
~/config/connectionstrings.config

Our testing proved that application restarts do happen when external config files were changed IF in web.config the section is declared with restartOnExternalChanges=”true”, except for AppSettings section....

<AppSettings> Exception to the Rule
AppSettings section won't accept restartOnExternalChanges attribute, so when specifying the external config file path you have to use "configSource=" to restart app on config file change, or "file=" to avoid restart.

Tuesday, 8 October 2013

Windows: Concatenate output from multiple commands & output redirection

I was trying to be creative and flex my rusty Windows shell/DOS/cmd scripting using findstr, nslookup and Windows/DOS command redirection...

I was having to repeatedly run the same commands over and over with as few keystrokes as possible:

ipconfig /flushdns >null 2>1 && nslookup SERVER1 && nslookup SERVER2 && ...
  • >null
    This gets rid of normal output (STDOUT, or Standard Output) from displaying on the screen.  Normally STDOUT is connected to the current terminal (command window), so I redirect to the built-in black hole, which is file descriptor 'null', or device /dev/null in UNIX/Linux.
  • 2>1
    This gets rid of error messages from the screen (STDOUT).  When redirecting both STDOUT and STDERR from a single command they have to appear in numerical order of their codes, so it goes STDIN(0), STDOUT(1), STDERR(2).  '2>1', effectively says "redirect file descriptor 2 (STDERR) to the same place that we've sent 1 (STDOUT).
  • &&
    I only want the subsequent nslookup commands to run if the first one, flushdns is successful (if its return code is >0, zero being success in Windows/DOS), so I use '&&' (same in UNIX/Linux).
Now I wanted to concatenate the output from all the commands into a single string and then strip out matching lines... Just wrap the commands in normal parentheses (like this):

( ipconfig /flushdns >null 2>1 && nslookup SERVER1 && nslookup SERVER2 ) | findstr /b "N A"

The 'b/' tells findstr to match beginning of lines.  Putting the search terms in double quotes separated with spaces means use logical ORs so it matches any one of them.  So we end up with the output we're looking for:

( ipconfig /flushdns >null 2>1 && nslookup SERVER1 && nslookup SERVER2 && nslookup SERVER3  ) | findstr /b "Server Name Address"
Server:  gs1gpcmadcv01.gphc.local
Address:  172.16.82.1
Name:    GPHCDMZWS01.gphc.local
Address:  172.17.82.10
Server:  gs1gpcmadcv01.gphc.local
Address:  172.16.82.1
Name:    GPHCDMZDWWS01.gphc.local
Address:  172.17.82.11
Server:  gs1gpcmadcv01.gphc.local
Address:  172.16.82.1
Name:    GPHCDMZDWSTG01.gphc.local
Address:  172.17.82.13

If wish I knew how to strip out the two lines that relate to the DNS server itself - it gives the name of the Server and its Address before the target host we're resolving.  Maybe grep/awk on UNIX/Linux would be easier than figuring out how to handle line breaks with findstr, which doesn't seem to handle them at all without some dos scripting black magic!

Wednesday, 21 August 2013

Using Windows 7 runas for dsa.msc mmc causes error 740: The requested operation requires elevation.

Microsoft's User Account Control in Windows 7 Professional

This is my first really bad experience with Microsoft's new User Account Control (UAC).  Something caused our long-used and well trusted service account to be disabled.

After installing Windows Server 2003 Administrative Tools Pack so I can use MMC snap-in "Domain Users and Computers" (dsa.msc) on my local PC and after a few runas error 193, I kept getting the following error message:

C:\>runas /user:"domain\username" "mmc %windir%\system32\dsa.msc"
Ento start mmc C:\Windows\system32\dsa.msc as user "domain\username" ...
RUNAS ERROR: Unable to run - mmc C:\Windows\system32\dsa.msc
740: The requested operation requires elevation.

The solution was to call 'cmd /c' which tells 'cmd' to open and run the command supplied as a parameter, which is our mmc command:

C:\>runas /user:"domain\username" "cmd /c mmc %windir%\system32\dsa.msc"
Enter the password for domain\username:
Attempting to start cmd /c mmc C:\Windows\system32\dsa.msc as user "domain\username" ...


...now it works! :)


Sunday, 4 August 2013

Oracle database connections lost contact across firewalls/networks

The Problem:

At work during the quietest periods of activity, our database connections would sometimes become unusable and create an exception when used.  It took us a lot of effort to track down the problem to firewalls killing them without ADO.NET knowing.  This tended to happen with Oracle and the exception was one of the following:
  • ORA-03135: connection lost contact
  • ORA-03113: end-of-file on communication channel
The comms goes like:

Internet-based-client =firewall=> DMZ service =firewall=> DB-on-private-LAN


The Cause

The connections were created in the DMZ and traversed the network boundary through the firewall and to the DBMS in the private LAN.  This firewall was set to automatically kill idle TCP/IP sessions after a max time period (I'm informed this is normal behaviour.  With connection pooling turned on (default), ADO.NET will only know a connection has been severed in this way the next time it tries to use it.

Example: User X uses our website, creating a new connection and once their website session ends, the connection is returned to the pool.  The firewall kills the TCP/IP session used by the database connection because it's timed out through inactivity.  User Y uses the website which tries to reuse the database connection and it fails with an exception.


The Solution

We can limit the max lifetime of a connection to prevent connections sitting idle for too long either:
  • Employ a custom solution for retrying, clearing connection pool, etc.
  • Using 'Connection Lifetime=XXXX' in the connection string.
  • Setting SQLNET.EXPIRE_TIME on the client (if using full, non-xcopy version of the Oracle client), or on the server (sqlnet.ora file in ORACLE_HOME\network\admin).

At first we employed a custom solution that retried opening connections, clearing pools and all sorts of black magic!.  Now we've learnt of connection string setting 'Connection Lifetime':


Connection Lifetime
  • MSDN: When a connection is returned to the pool, its creation time is compared with the current time, and the connection is destroyed if that time span (in seconds) exceeds the value specified.  Default is 0.
  • To mitigate against severed connections eg across firewalls and networks, ensure to set a timeout value.  We're starting with a value of 3200 (1hr).