In Windows, you can edit an application shortcut and change the shortcut's target. How do you do this in Mac OS?

For example, I want to change my Chrome application to do verbose logging, by appending this to the run command: --enable-logging --v=1.


You can use Automator or AppleScript to make an app that launches the app with specific arguments:

-- Applescript version
do shell script "open -a 'Google Chrome' --args --enable-logging --v=1"

Or you can go into the app bundle and modify the Info.plist, changing CFBundleExecutable from (for example) "Google Chrome" to the name of a new wrapper script that you put in MacOS. Here's a Python script that automates that for you (It actually makes a new app with symlinks). Run it with python linkapp.py<path to actual app> <where to put new app> in Terminal. When it asks you whether to create a wrapper script, answer y.

(the script is now on GitHub, but I'll try to keep this one updated)

#!/usr/bin/env python

import sys
import os
import shutil
import subprocess
import re

#!/usr/bin/env bash
executable="$(dirname "$0")/%s"

# add flags here.

def printerr(message):
    sys.stderr.write("\033[1;31m" + message + "\033[0m")

def link_item(item):
    os.symlink(os.path.join(bundle_contents_path, item),
               os.path.join('.', item))

def replace_executable(filename, new_executable):
    old_executable = subprocess.check_output(['defaults', 'read', os.path.abspath(filename), 'CFBundleExecutable'])
    old_executable = old_executable.rstrip()
    subprocess.call(['defaults', 'write', os.path.abspath(filename), 'CFBundleExecutable', new_executable])
    return old_executable

if len(sys.argv) <= 2:
    printerr("Usage: linkapp.py <app-bundle> <new-place>\n")

bundle_path = os.path.abspath(sys.argv[1])
bundle_contents_path = os.path.join(bundle_path, 'Contents')
new_contents_path = os.path.abspath(os.path.join(sys.argv[2], 'Contents'))

# loop through the app bundle and symlink everything
#                                        (except Resources, MacOS & Info.plist)
for i in os.listdir(bundle_contents_path):
    if i.lower() != 'info.plist':
        if i.lower() in ['resources', 'macos']:
            for j in os.listdir(os.path.join(bundle_contents_path, i)):
                link_item(os.path.join(i, j))

# just copy Info.plist for easy editing
shutil.copy(os.path.join(bundle_contents_path, 'Info.plist'), new_contents_path)
subprocess.call(['plutil', '-convert', 'xml1', 'Info.plist'])

printerr("Create wrapper script [y/n]? ")
ans = sys.stdin.read(1)
if ans.lower() == 'y':

    wrapper_script_file = 'run_with_specified_arguments.sh'

    original_executable = replace_executable('../Info.plist', wrapper_script_file)

    with open(wrapper_script_file, 'w') as f:
        f.write(WRAPPER_SCRIPT % original_executable)
    os.chmod(wrapper_script_file, 0755)

    subprocess.call(['open', '-R', wrapper_script_file])

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .