Skip navigation

Tag Archives: bash

Escaping a forwardslash in awk like

awk  '/javascript\//'

doesn’t work
The way to do so is using the hexadecimal value of “/” which you can figure with the “od” unix command:

echo "/" | od -x

which returns:
0000000 0a2f
0000002

then doing:

awk '/javascripta2f/'

works fine!

Advertisements

Due to a disk failure on a server I needed to preserve several databases created for students. Some of them were empty, consecuently doing:
mysqldump with the option --all-databases yielded an error and didn’t work.

What worked instead, was iterating through and mysqldumping them individually with this shell oneliner:

for I in $(mysql -uroot -p****** -e 'show databases'); do  mysqldump -uroot -p****** $I > $I.sql; done;

I compressed those created files into one tar inmediately after:

ls -1 | xargs tar -cvzf backupOfDatabases.tgz

Writing heredocs in the shell from emacs presented to me a little nuisance: since the RETurn key is bound to ‘comint-send-input -a function that sends the text to the shell process- I coudn’t re-edit the previous line after having pressed it to insert a simple line break. (I should add that this is actually the usual unix bash behaviour, I only happen to use bash from emacs and so wanted to overcome the problem there)

Yesterday it dawned on me to just use “C-q C-j” under that situation, (that’s how you stick in a line feed in emacs regardless of the mode you are in).

Given that the perspective of typing “C-q C-j” several times looked rather awkward I thought of binding RET with the control key for that:

(global-set-key (quote [(control return)]) (quote newline))

But then, the idea of going the other way around showed more appealing: why not to make newlines with a simple RET, and use the Control key to send the input? Besides, it makes sense to prevent hitting return by accident, I hate when my pinky lands there when searching the pipe “|” key.

While at it I decided to also rebind the TAB functionality so I could further improve the readability of my scripts by indenting them at the same time.

Implementing those changes is simple when you’ve got the luxury of a highly-configurable tool:

(defun my-shell-hook ()
  (local-set-key (quote [(return)]) (quote newline))
  (local-set-key (quote [(control return)]) (quote comint-send-input))
  (local-set-key (kbd "M-i")  'my-unindent)
  (local-set-key (kbd "C-i")  'indent-or-complete))

(add-hook 'shell-mode-hook 'my-shell-hook)

UPDATE: After a day trying this set-up I think that I’d rather stick to the normal binding of the RET key. I’m leaning toward using C-j and C-m instead, as I caught myself reaching to either of them to insert carriage returns. Here are the modified bindings in replacement:

(defun my-shell-hook ()
  (local-set-key (kbd "M-i")  'my-unindent)
  (local-set-key (kbd "C-i")  'indent-or-complete)
; (local-set-key (quote [(return)]) (quote newline))
; (local-set-key (quote [(control return)]) (quote comint-send-input))
;; I actually liked these two better for adding  newlines, leaving the return with it's default behavior
  (local-set-key (quote [(control j)]) (quote newline))
  (local-set-key (quote [(control m)]) (quote newline))
  (local-set-key (quote [(return)]) (quote comint-send-input)))


(add-hook 'shell-mode-hook 'my-shell-hook)

I picked a neat trick at http://stackoverflow.com/ to cancel a command from the shell with “C-q C-c RET” if I need to interrupt a process in a remote shell opened via tramp (only with my windows laptop which I run with cygwin and emacs 23.1.91.1)

Until now, without it, I found it very frustrating for example trying to cancel a heredoc inside a shell: due to some obscure reason, typing “C-c C-c(comint-interrupt-job) rather than get me back at the shell prompt, would kill the connection with the message “Process shell interrupt”.

Again though this alternative is only necessary to me when connected to remote hosts using the windows version of emacs, it’s a sweet discovery nonetheless.

Now that I’m getting fond of using a heredoc to insert mysql scripts into the bash shell, have put this into my emacs initialization file. The same shortcut (Control+Shift+f11) will conveniently write different parameters depending in which shell I’m sitting in.

UPDATE: seems that I spoke too soon. Asking about the present working directory, formerly “(let ((a (shell-command-to-string “pwd | tr -d ‘\\n'”)))”, didn’t actually work when having opened shells of different servers via Tramp.
The correction below (less elegant) depends on the shell buffer being created/renamed with an identifiable name -which could be the hostname or whatever consistent nomenclature we choose-.
Anyway, until figuring a better way, this does the job of inserting the right parameters into each shell:

(defun my-heredoc-sql-invocation-from-shell ()
"Insert the appropiate parameters to run a heredoc mysql query depending on which shell I'm in"
  (interactive)
  (let ((a (buffer-name (window-buffer (minibuffer-selected-window))))
        (b nil))
    (cond ((string-match "serverA" a) 
           (setq b "mysql -uroot mainDbToHitAt_A--password=`cat /etc/security/mysqlpassword` -t -vv <<\\!"))
          ((string-match "serverB" a) 
           (setq b "mysql -ualpha mainDbToHitAt_B --password=`cat /etc/security/mysqlpassword` -t -vv <<\\!"))
          ((string-match "serverC" a) 
           (setq b "mysql -uroot mainDbToHitAt_C  -t <<\\!")))
    (insert b)))

;; key shortcut to bind it to
(global-set-key (kbd "C-S-<f11>")  'my-heredoc-sql-invocation-from-shell)

Despite being dealing with databases for some years it was just recently that I started to run mysql queries straight from the shell by doing something like:

mysql -u(user) -p(password)  -t -e ‘whatever sql query here in one line’

Although a handy way to use every now and then, I still felt this sort of limited since the query to be passed in the “-e” argument must go inside a single line. In search of  a better alternative I was pleased to figure instead that it’s possible to combine heredoc sintaxis with the sql execution in the command line. Heredoc is a mechanism to break text into multiple lines, just as a file would be treated, after the “<<” sign, the parser says: “here follows a document” which gets wrapped inside the pair of whatever text delimeters we choose. The obvious convenience is that without having to create a file we could easily run multiline queries -which read more naturally with line breaks and indentation- in the same way we would write them inside a file.

To quickly see what I’m talking about type

mysql -u(yourDatabaseUserName) -p(your Password)   -t<<eof
show databases
eof

Now hit “Control D” and then, “Enter” to see the output directly thrown at your shell

To speed things up, since  I use the shell inside emacs, I bound the following to C-S f11 adding  what is below into my .emacs file:

(set-register ?q “mysql -u kabul -p ******** -t <<eofsql”)
(defalias ‘Q
(read-kbd-macro “M-x insert-register RET Q C-e “))
(global-set-key [C-S-f11] ‘Q)

I sometimes forget about the exact name of a file I was working a while ago. Luckily the way to state a range of time with find is quite intuitive; say that we want to see the files modified in a lapse of 14 days starting from a week ago:

find . -ctime +7  -ctime -21 # (older than 7 days but newer than three weeks ago)

There are simply 3 options of numeric arguments for time

  1. +n –> More than ‘n’ days ago.
  2. -n –> Less than ‘n’ days ago.
  3. n —> Exactly ‘n’ days ago.

For those that haven’t had the chance to use it, wget is a powerful gnu application that allow to retrieve content non interactively from the web, which makes it ideal to an array of sys-admin tasks. It gets a bit hard to tame so much power and you need to craft the outcome by carefully picking inside the command options. Something practical, like downloading the entire or partial content from inside a folder and its sub-folder, for example, requires a couple of parameters to be passed so not to get confused by the unintuitive way the program goes about retrieving upper-level directories along with the desired stuff.
When you specify the recursive option (-r) to address a site path like http://somesite.com/folder/subfolder/ you would reasonably expect to get every content from that point down the directory tree (much in the fashion that cp -rf would do it, coping all in the hierarchy below) but given the weird behavior of fetching other directories above, the extra option ‘–no-parent’ proves essential.

Along with those two I normally include a couple of extra parameters:

:: ‘-nv; (or ‘–no-verbose‘) that turns off verbose output, without being completely quiet, which means that errors messages and basic information still get printed;

:: ‘-nH‘ (‘or –no-host-directories‘) that disable the generation of host-prefixed directories. By default, invoking wget with ‘-r http://somesite.org&#8217; will create a structure of directories beginning with http://somesite.org

The hypothetical example then will look something like:

wget -r -np -nv -nH  http://www.addressedSite.info/coolJavascriptLib/

The simple solution with awk is doing:

awk ‘{print $NF}’

This is useful when like in the following  we want to list just files skipping directories:

ls -l | awk ‘NR!=1 && !/^d/ {print $NF}

There are other options of course, take a look at this example from a nice collection of bash and unix tips

 

 

This is how I quickly pull and insert the subversion path within the emacs shell, as I often need the absolute URL when restoring to a file to previous version for example.

(defun svn-root ()
"get path to svn repository"
(interactive)
(insert (shell-command-to-string "svn info | awk -F ':' '/URL/' | cut -c 6- | tr -d '\n'")))