Creating command line alias with python

2019-04-30 00:19发布

问题:

I want to create command line aliases in one of my python scripts. I've tried os.system(), subprocess.call() (with and without shell=True), and subprocess.Popen() but I had no luck with any of these methods. To give you an idea of what I want to do:

On the command line I can create this alias: alias hello="echo 'hello world'"

I want to be able to run a python script that creates this alias for me instead. Any tips?

I'd also be interested in then being able to use this alias within the python script, like using subprocess.call(alias), but that is not as important to me as creating the alias is.

回答1:

You can do this, but you have to be careful to get the alias wording correct. I'm assuming you're on a Unix-like system and are using ~/.bashrc, but similar code will be possible with other shells.

import os

alias = 'alias hello="echo hello world"\n'
homefolder = os.path.expanduser('~')
bashrc = os.path.abspath('%s/.bashrc' % homefolder)

with open(bashrc, 'r') as f:
  lines = f.readlines()
  if alias not in lines:
    out = open(bashrc, 'a')
    out.write(alias)
    out.close()

if you then want the alias to be immediately available, you will likely have to source ~/.bashrc afterwards, however. I don't know an easy way to do this from a python script, since it's a bash builtin and you can't modify the existing parent shell from a child script, but it will be available for all subsequent shells you open since they will source the bashrc.


EDIT:

A slightly more elegant solution:

import os
import re

alias = 'alias hello="echo hello world"'
pattern = re.compile(alias)

homefolder = os.path.expanduser('~')
bashrc = os.path.abspath('%s/.bashrc' % homefolder)

def appendToBashrc():
  with open(bashrc, 'r') as f:
    lines = f.readlines()
    for line in lines:
      if pattern.match(line):
        return
    out = open(bashrc, 'a')
    out.write('\n%s' % alias)
    out.close()

if __name__ == "__main__":
  appendToBashrc()


回答2:

Here's a simplified analog of the code from @Jonathan King' answer:

#!/usr/bin/env python3
from pathlib import Path  # $ pip install pathlib2 # for Python 2/3

alias_line = 'alias hello="echo hello world"'
bashrc_path = Path.home() / '.bashrc'
bashrc_text = bashrc_path.read_text()
if alias_line not in bashrc_text:
    bashrc_path.write_text('{bashrc_text}\n{alias_line}\n'.format(**vars()))

Here's os.path version:

#!/usr/bin/env python
import os

alias_line = 'alias hello="echo hello world"'
bashrc_path = os.path.expanduser('~/.bashrc')
with open(bashrc_path, 'r+') as file:
    bashrc_text = file.read()
    if alias_line not in bashrc_text:
        file.write('\n{alias_line}\n'.format(**vars()))

I've tried and it works but you should always create a backup file when changing sensitive files:
$ cp ~/.bashrc .bashrc.hello.backup