Article 5BMTB Shells, quoting, and one-liners

Shells, quoting, and one-liners

by
John
from John D. Cook on (#5BMTB)

The goal this post is to show how to call Perl and Python one-liners from a shell. We want to be able to use bash on Linux, and cmd or PowerShell on Windows, ideally with the same code in all three shells.

Bash

Bash interprets text inside double quotes but not in single quotes. So if you want to send a string to a program unmolested, you surround it with single quotes.

For example, suppose I want to write a Perl one-line program to print hello. This works:

 perl -e 'print "hello\n"'

The single quotes tell the shell to pass what's inside to perl without doing anything to it.

The corresponding Python example would be

 python -c 'print("hello\n")'

and this also works.

Cmd and PowerShell

For reasons I don't understand, the Perl example above works from cmd, but the Python example does not.

And neither example works in PowerShell. This is particularly puzzling since PowerShell follows basically the same quoting rules as bash: double quotes interpolate but single quotes do not.

Workarounds

There are ways to fix the problems with cmd and PowerShell without breaking bash.

Perl

Perl has a handy feature for avoiding confusion over quotes: you can use q{} for single quotes and qq{} for double quotes. If I write the Perl example as

 perl -e 'print qq{hello\n}'

then it works everywhere: bash, cmd, and PowerShell.

Python

Python makes no distinction between single and double quotes, so you can reverse the role of single and double quotes to avoid quoting confusion. The code

 python -c "print('hello\n')"

works everywhere.

Printing quote marks

In the previous section we said we can get around problems in Perl by using q{} and qq{}, and get around problems in Python by switching to double quotes on the outside and single quotes on the inside. But what if we wanted to print a single or double quote mark, such as printing 'hello' or "hello"?

You can escape single quotes with \' and double quotes with \", but you run into things that work on cmd but not on bash, or work on bash but not in PowerShell, etc.

One sure-fire way to make quotes work, in Perl and in Python, and on every shell we're considering, is to denote quotes by their Unicode values, i.e. to use \x27 for single quotes and \x22 for double quotes. The one-liners

 perl -e 'print qq{\x27hello\x27\n}'

and

 python -c "print('\x27hello\x27\n')"

print 'hello' in bash, cmd, and PowerShell.

And similarly

 perl -e 'print qq{\x22hello\x22\n}'

and

 python -c "print('\x22hello\x22\n')"

print "hello" in bash, cmd, and PowerShell.

Guidelines for portable one-liners

In summary, you can avoid problems with Perl one-liners by using q{} and qq{} inside code rather than single or double quotes. For Python one-liners, you can swap single quotes and double quotes.

On Linux (bash) surround code with single quotes. On Windows (cmd and PowerShell) surround code with double quotes.

Use character codes for literal quote characters. This isn't necessary, but if you do this you won't have to remember how quotes and escapes work on different platforms.

Further readingThe post Shells, quoting, and one-liners first appeared on John D. Cook.7SccxTZBaH0
External Content
Source RSS or Atom Feed
Feed Location http://feeds.feedburner.com/TheEndeavour?format=xml
Feed Title John D. Cook
Feed Link https://www.johndcook.com/blog
Reply 0 comments