I use a Mac (osx sierra) and I have been learning how to use the bash. I am trying new stuff as I go along to grasp some concepts. This time I was experimenting with functions and aliases. But then I couldn't wrap my head around this problem:
I first echoed this function into the .profile to insert new aliases and functions easily into the .profile file.
function editprofile(){
echo "$@" >> ~/.profile
}
This function worked very well for some alias insertions. But after I tried to insert an alias for the script (the script below) that makes my mac sleep, I realized that the function creates some diffuculties with the cascading single and double quotes. I believe this will be the case for most scripts that uses lots of layers of single and double quotes.
osascript -e 'tell application "Finder" to sleep' && exit
The code below is me trying to use my function to insert the code above as an alias into the .profile.
editprofile 'alias _sleep=' "'" 'osascript -e' "'" 'tell application "Finder" to sleep' "'" '&& exit' "'"
The problem is that when the second script is echoed into the .profile file, I should still keep some escape characters, otherwise the code is interpretted by the bash incorrectly. I think this would also be the case with may other scripts that have this many layers of quotes, so I though I should ask if there is any way around.
P.S. On a related note, it seems like when I type this:
function editprofile(){echo "$@" >> ~/.profile}
instead of this:
function editprofile(){
echo "$@" >> ~/.profile
}
into the .profile file, the script doesn't work. Is it because of the line breaks?
Assuming that you have a function, as opposed to an alias:
_sleep() { osascript -e 'tell application "Finder" to sleep' && exit; }
...you can emit its text with declare -f
. Thus:
declare -f _sleep >>~/.profile
...or, to use your existing editprofile
function:
editprofile "$(declare -f _sleep)"
The easiest approach is just that: Define the function in your local shell, then have the shell itself do the work of emitting it -- and quote that emitted content so it doesn't get field-split into individual arguments (and then have those arguments individually evaluated as globs).
If you don't want to go that route, there are approaches available; they're just varying degrees of unpleasant.
printf -v cmd_var '%q ' osascript -e 'tell application "Finder" to sleep'
...will put correctly-quoted contents into "$cmd_var"
. You could then:
printf -v sleep_def '_sleep() { %s && exit; }' "$cmd_var"
...which will give you a function declaration in sleep_dev
that can be eval
ed to execute it locally, or appended to your .profile
, &c.
editprofile "$sleep_def"
...will behave appropriately in that context.