Mac OS X: edit .plist files from CLI

A number of methods are available that involve “tools” either requiring installatins or some form of previous knowledge about the .plist file contents.
As everything we need is already embedded within the OS (tested with 10.8.5), I’ll just go ahead and describe my manual method:

  1. convert the .plist file (or a copy!) from binary1 (default/original format) to the format of your preference (xml1 or json)
  2. plutil -convert xml1 <filename>
  3. edit the file
  4. vi <filename> :)
  5. convert the file back to binary1 format
  6. plutil -convert binary1 <filename>

Show progress during dd copy

Ok, this is actually a copy and paste post thus credit is due where credit is deserved: Linux Commando.

The quick-and-dirty trick: open a new terminal and enter:

$ kill -INFO <PID of dd process>

NOTE: do not use USR1 on Mac OS X!

The “output” will be printed on the console where dd is actually running:

$ dd if=/path/to/file of=/dev/sdb1 bs=1M
0+14 records in
0+14 records out
204 bytes (204 B) copied, 24.92 seconds, 0.0 kB/s

[131028 update]: in fact $ sudo pkill -INFO -n -x dd seems to be a much quicker, and easy to remember, one-liner.

Source: RPi Easy SD Card Setup

List all files in a directory, order by date

Nothing original, the Internet is full of good recommendations, but I had to come up with my own answer:

  1. cd to the upper-level directory
  2. run:  find . -type f -print0 | xargs -0 ls -rtl | awk '{print $6 " " $7 " " $8 " " $9}'

Explanation:

  • find recursively looks for regular files starting from the current directory, output is a long uninterrupted list
  • xargs is used to pass the above output to ls which will display in reverse order, by time, in long format
  • awk will select only the relevant fields

Compare hex files in Mac OS X (strings, hexdump)

diff or sdiff built-in utilities make it easy to compare text files:
example file txt1.txt

line #1
line #2
line #3

example file txt2.txt

line #1
line #2
line #4 <<<===this is where difference lies from the above file

Both diff and sdiff will give us a precise indication of which differences exist and where they are:

$ diff txt1.txt txt2.txt 
3c3
< line #3 <===this is the contents of the first argument ("<", left file)
---
> line #4 <===this is the contents of the second argument (">", right file)

$ sdiff txt1.txt txt2.txt
line #1                         line #1
line #2                         line #2
line                       |    line #4 <===files are shown side-by-side
                                            and differences highlighted

Now what would occur with two different binary files is:

$ diff bin1.bin bin2.bin 
Binary files bin1.bin and bin2.bin differ

Evidently that’s not enough for us…
Well, there’s built-in tools that would be useful in highlighting some discrepancies, namely strings and hexdump. Let’s take a look at both of them with some examples.

1. strings command is able to find any “printable” objects in a file:

$ strings bin1.bin 
_DYNAMIC
_GLOBAL_OFFSET_TABLE_
__gmon_start__
_init
...

You might notice this can be a long output, hmmm… What about the following?

$ strings bin1.bin | grep -i version
version 5.0.0.5, build 0

Whereas:

$ strings bin2.bin | grep -i version
version 4.1.0.7, build 0

Of course “version” is just an example but quite relevant IMHO. Up to you to identify a string that would be meaningful for a comparison.

2. even more detailed, hexdump command, as its name implies, can show you the entire contents of the file along with the hex-to-ASCII translation, for instance:

$ hexdump -C bin1.bin 
00000000  7f 45 4c 46 01 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
00000010  03 00 03 00 01 00 00 00  e0 1d 00 00 34 00 00 00  |............4...|
00000020  b8 88 00 00 00 00 00 00  34 00 20 00 04 00 28 00  |........4. ...(.|
00000030  21 00 1e 00 01 00 00 00  00 00 00 00 00 00 00 00  |!...............|
...

In this case the suggestion is to redirect the output to a text file that can be examined with diff or sdiff, or your favourite tools, later on.

Start an FTP (or TFTP or SFTP) server on Mac OS X (10.7+)

FTP

Since upgrading to Lion (10.7) the option to enable the FTP server has disappeared for, I assume, security reasons.

Nonetheless, an FTP server is still available to the user. Let’s see how it can be started from a CLI one-liner:

$ sudo -s launchctl load -w /System/Library/LaunchDaemons/ftp.plist

You can immediately confirm that by trying:

$ ftp localhost

NOTE: files will be served from the user’s home directory.

To stop the FTP server just issue:

$ sudo -s launchctl unload -w /System/Library/LaunchDaemons/ftp.plist

TFTP

To start/stop a TFTP server replace ftp.plist with tftp.plist.
The source directory in this case will be /private/tftpboot.
NOTE: the files must be readable.

SFTP

As fas as SFTP (S=secure) goes instead, this can be enabled through System Preferences’ Sharing application. It’s not explicitly mentioned but if Remote Login (SSH) is on then the computer’s IP address will also respond to SFTP/SCP requests.

For the tech-savvy, yes, this is better referenced to as FTP over SSH.

Source: http://osxdaily.com/2011/09/29/start-an-ftp-or-sftp-server-in-mac-os-x-lion/

Instant Python HTTP server

The quick and dirty way of starting an instant web server is by means of Python‘s simple HTTP request handler.

The following command will start listening to HTTP requests on port <port> (if <port> is blank a default value of 8000 is assumed) and will be serving files from the current directory:

$ python -m SimpleHTTPServer <port>

On the host’s console the access log will be displayed (example):

Serving HTTP on 0.0.0.0 port 4444 ...
<source address> - - [16/May/2013 12:12:17] "GET / HTTP/1.1" 200 -
<source address> - - [16/May/2013 12:12:17] "GET /favicon.ico HTTP/1.1" 404 -
<source address> - - [16/May/2013 12:12:19] "GET /example_file.txt HTTP/1.1" 200 -
...

To stop the server, according to the above-mentioned quick and dirty approach, issuing CTRL+C is fine (a traceback will be printed by the Python interpreter, that’s not something to worry about).

Source: http://osxdaily.com/2010/05/07/create-an-instant-web-server-via-terminal-command-line/

tree-like ls

tree” is a very nice command that’s not always available on any systems. As the name implies it lists the contents of directories in a tree-like format.

An example is:

$ tree
.
|-- Boards
|-- Members
|-- Messages
|-- Settings.pl
|-- Sources
|-- Variables
|-- YaBB.cgi
|-- english.lng
|-- template.html
`-- template2.html

Well, a similar result can be achieved in Bash with a nifty little one-liner:

ls -R | grep ":$" | sed -e 's/:$//' \
   -e 's/[^-][^\/]*\//--/g' -e 's/^/   /' -e 's/-/|/'

NOTE: long line, I had to break/fold it, sorry about that. Copy&paste is fine as long as the backslash (“\”) at the end of the first line is preserved.

A short explanation of the cryptic syntax above is as follows:

  • initially a recursive listing of the current directory is done: ls -R
  • pipe
  • any output other that the directory names, identified by “:” at the very end of each line (hence “:$“), is filtered out: grep ":$"
  • pipe
  • finally there’s a little of “sedmagic finding and replacing any hierarchy level (“/“) with one or more dashes (“-“):
    sed -e 's/:$//' -e 's/[^-][^\/]*\//--/g' -e 's/^/ /' -e 's/-/|/'