Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to know what script header to use and why it matters?

I infrequently have to write bash scripts for various unrelated purposes and while I usually have a good idea what commands I want in the script, I often have no idea what header to use or why I'm using one when I do find it. For example(s):

  • Standard shell script:
    • #!/bin/bash
  • Python:
    • #!/usr/bin/env python

Scripts seem to work fine without headers but if headers are the standard, there's a reason for them and they shouldn't be ignored. If it has an effect, then it's a valuable tool that could be used to accomplish more.

Minimally, I'd like to know what headers to use with MySQL scripts and what the headers do on Standard, Python, and MySQL scripts. Ideally, I'd like a generic list of headers or an understanding of how to create a header based on what program is being used.

like image 927
Still.Tony Avatar asked Dec 20 '22 18:12

Still.Tony


1 Answers

How the Kernel Executes Things

Simplified (a bit), there are two ways the kernel in a POSIX system knows how to execute a program. One, if the program is in a binary format the kernel understands (such as ELF), the kernel can execute it "directly" (more detail out of scope). If the program is a text file starting with a shebang, such as

#!/usr/bin/somebinary -arg

or what-have-you, the kernel actually executes the command as if it had been directed to execute:

/usr/bin/somebinary -arg "$0"

where $0 here is the name of the script file you just tried to execute. (So you can immediately tell why so many scripting languages use # as a comment-starter – it means they don't have to treat the shebang as special.)

PATH and the env command

The kernel does not look at the PATH environment variable to determine which executable you're talking about, so if you are distributing a python script to systems that may have multiple versions of python installed, you can't guarantee that there will be a

#!/usr/bin/python

env, however, is POSIX, so you can count on it existing, and it will look up python in PATH. Thus,

#!/usr/bin/env python

will execute the script with the first python found in your PATH.

BASH, SH and Special Meanings for Invocation

Some programs have special semantics for how they're invoked. In particular, on many systems /bin/sh is a symlink to another shell, such as /bin/bash. While bash does not contain a perfectly POSIXLY_STRICT implementation of sh, when it is invoked as /bin/sh it is stricter than it would be if invoked as plain-old-bash.

MySQL and arg limitations

The shebang line can be length limited and technically, it can only support one argument, so mysql is a bit tricky – you can't expect to pass a username and database name to a mysql script.

#!/usr/bin/env mysql
use mydb;
select * from mytbl;

Will fail because the kernel will try mysql "$0". Even if you have your credentials in a .my.cnf file, mysql itself will try to treat "$0" as a database name. Likewise:

#!/usr/bin/mysql -e
use mydb;
select * from mytbl;

will fail because again, "$0" is not a table name (you hope).

There does not seem to be an appropriate syntax for directly executing a mysql script this way. Your best bet is to pipe the sql commands to mysql directly:

mysql < my_sql_commands
like image 93
kojiro Avatar answered Dec 28 '22 08:12

kojiro