alfred-documentation
alfred-documentation copied to clipboard
How can I access Alfred Specific Environmental Variables?
All these variables sounds fantastic. How can I access them?
- From a script filter, with the code right in alfred's window, with every language?
- From a script filter, with an external script called through something like
script.sh "{query}", can I still access them? - Where else? How else?
This page is a good dictionary but sorta lacks a little paragraph to explain it :-)
https://github.com/shawnrice/alfred-documentation/wiki/Alfred-Specific-Environmental-Variables
The page also has ugly formatting. Right now, I just did a sort of content dump to get the information up there. Again, feel free to edit anything; after all, it is a community wiki.
Yes, you can access them. The syntax is language dependent.
For Bash, it's just the variable name: alfred_version is $alfred_version.
For PHP, you can grab them from globals (I think the $_SERVER variable is the easiest access, but I'd need to check): $_SERVER['alfred_version'].
For Ruby, if I remember correctly, it would be $ENV['alfred_version'].
For AppleScript, I think that you have to grab them from a do shell script command, but there probably is something more direct.
Basically, the way that Alfred works is that it exports the variables into a Bash shell, and then it runs the script from the command line; hence, any environmental variables that are exported to the shell are available to the script being run with the exception of a few special types of sub-shells.
Where did you get this info from? This documentation is such a good idea, for now it's a horrible mess to find anything reliable!
Well, especially with newer features, the documentation is lacking, and so it's been stuff that we've had to figure out on our own, and so the best source comes from trial and failure that has been documented on the forums. Vero and Andrew are making a sincere effort to update the documentation for Alfred, but, in order for it to work for a general audience, it can't get too technical. Keep in mind that the main workflow authors that you find across Packal and the forums provide some of the most intense and complicated workflows that many others just use, so we're a much smaller audience (Alfred is pretty damn huge). Most workflows written are private and never shared. Maybe they're too bespoke to be shared, or the workflow author doesn't care about sharing (or doesn't have the time and/or skill to make them generic enough to be shared). Based on my conversations with Andrew, I know that, after Alfred Remote, he's going to throw much of his coding effort into improving workflows, especially the developer experience. I do know a few more details, but I'm not allowed to share what those are, sadly. But they should make our lives as developers easier and make it so that many others can write workflows that are easier to share.
But, this wiki is meant to supplement the official documentation in order to provide much more technical detail that would go over many workflow authors' heads but also to document the esoteric and idiosyncratic behavior that Alfred has. Honestly, I think that we need to beef-up the "Common Errors" page and create a more general "FAQ" page that would serve as an entry-point/Table of Contents for the general user of this wiki.
For this info: I either figured it out or found clues on the forums. Honestly, Dean and I have exchange (as a low estimate that is not exaggerated at all) 1000+ emails about Alfred's behavior and development issues (and beer). We've pushed each other to figure out exactly how these things worked and shared many, many a test result (write a workflow script in three different ways, and run it 1000 to 1 million times to check performance on SSD and standard hard drives — figure out if it works faster in Ruby, PHP, Python, or Bash). We're also both good at correcting each other when we're not precise enough (he's better at being precise than me).
So, basically, these come from a mix of tests, an understanding of how Alfred runs workflows, and an understanding of Bash subshells. If you run top or htop in a terminal window and then launch a bunch of different Alfred workflows, you'll see that Alfred just runs them the way you would from the command line (i.e.: php -r "print_r($_GLOBALS);"), and it nicely escapes everything for you nicely (hence the escaping checkboxes — they are bash escape sequences). If you create some long-running script-filters and then launch them over and over again, you'll see Alfred executing all of the commands, waiting for them to finish before moving on to interpret the results. Running them via the command line also shows why Alfred will never support NodeJS natively: it supports only those built in that can run scripts from the command line. A major, major rewrite of Alfred would be necessary in order to support anything else.
When you launch, for instance, PHP (and I'll stick with PHP from here on out because I know you know it well), you call the PHP binary to interpret a PHP script, and, as it's called from a Bash shell (keeping in mind that Bash is the native shell on OS X), it inherits Bash's environmental variables. The same is true for starting a PHP server instance: it inherits those variables (otherwise $_SERVER would always be empty).
As an aside — you and I have worked out that way to speed up workflows by launching a pop-up PHP server to process the scripts. If you left that server running from one workflow and took advantage of it form another workflow, then it would have the wrong Alfred-set environmental variables. If you created if outside of Alfred and then ran it, it would have no Alfred-set environmental variables. Actually, I can't say that for sure because I'd need to know more about how the pop-up server (which might be different than PHP-FPM or mod_php) processes scripts. It might inherit the environmental variables from the script call, in which the Alfred-set variables would always be set correctly). But, that shows the matter of taking the logic of how they work and testing them to make sure that they actually work that way. Often, the two diverge.
As another instance, I figured out how the environmental variables work based on these logics (granted, Dean indicated that $_SERVER would probably contain many of the environmental variables), but then I just tested them. My method was to create an empty workflow with a script filter that was PHP and just had print_r($_GLOBALS); in it. Then, I ran that with the Alfred debugger open to make sure that STDERR had what I expected. I then repeated it with a Bash subshell that ran the same contents of the PHP script (php script.php that contained print_r($_GLOBALS);. Then I repeated it the same way with each scripting language to make sure that they all worked like that.
They did.
So, to summarize this long response: Alfred launches a shell that runs workflows basically like the command line. It sets the environmental variables by, basically (or maybe actually) running export alfred_version=2.5, etc... when launching the shell; and it runs it as your user (you can verify this with top or htop), but it doesn't source ~/.bashrc wisely (which is also a troubleshooting issue raised all-to-often in the forums). You can verify this by setting an environmental variable in your ~/.bashrc file, calling it (to find it blank as Bash does), then source ~/.bashrc and finding it. Use the script debugger to verify that Alfred behaves what you expect. Use top/htop to watch Alfred work (use homebrew to install htop if you haven't already).
And, mostly, edit/update this wiki often. If you just have some information that you think should be included, then throw it in even if you don't have time to do it well. Then, either someone else will format / clarify / expand it, or you can do it later when you have time. If there is a topic that should be covered, then create a stub page that has simply a description of what should be included, and make sure that you create an obvious link to it on something like the main wiki page so others see it. And, if you have time to organize/clarify what other people have simply dumped in here, then go for it. If you get it a bit wrong, then someone else will correct it. After all, it is a community wiki and will be only as good as much as the community's effort (and it will be nice, in the forums, just to provide a link to the answer on the wiki).
If you see a great forum post that explains a problem that should be documented, copy/paste it into this wiki (and credit the author). You know.
After thinking about it more, we need to create a page / section on UI scripting: how to enable it and how to make it work with many languages. Alfred is written in English (as is most of the internet and software: just note what the nouns/verbs are for most shell commands / functions in most languages), which means that, when it has to deal with other languages, it sometimes fails. And, since the forums are in English, most documentation is in English. (If you want to translate some of this into French, go for it!). But Alfred's user-base (and many people who use our workflows) is international, so things will fail if we don't code in support for, say, Korean. (I have, in the back of my mind, an easy-to-use and hard-to-write framework for internationalizing Alfred Workflows). Dean has really worked with unicode problems in Python to make this work with multiple languages.
Anyway. That was a long response to a short question.
Where did you get this info from? This documentation is such a good idea, for now it's a horrible mess to find anything reliable!
It's cobbled together from scraps scattered across the forum and much poking of Alfred with a stick to see which info on the forum is actually correct and where it is incomplete.
The hope was that it would serve as a starting point, so that others would jump in and add a bit here and there.
Alfred launches a shell that runs workflows basically like the command line
Technically, it doesn't run a shell. It runs the process (bash, ruby, python etc.) directly, presumably using NSTask.
Dean has really worked with unicode problems in Python to make this work with multiple languages.
Of course. I use German every day. If making my stuff work with a language I need didn't also make it work with other languages, I dare say it probably wouldn't…
And getting non-ASCII text to work with Python 2 is a bit of a bitch that isn't at all obvious to novice coders.
I should maybe add a page about text encoding/Unicode in Python to the wiki.
Technically, it doesn't run a shell. It runs the process (bash, ruby, python etc.) directly, presumably using NSTask.
See, there he goes again doing the being-more-precise thing.
I should maybe add a page about text encoding/Unicode in Python to the wiki.
That seems like a good idea.
See, there he goes again doing the being-more-precise thing.
:grinning: I know I'm being anal, but you say "shell" and then someone asks why *.mp3 doesn't work…
That seems like a good idea.
I have a page on it in the Alfred-Workflow docs, but I'm not very happy with it.
It's quite a complex topic and it's hard to know where to start. It should probably be a 5-part tutorial on its own…
I wish Python just worked with encoded text and/or used UTF-8 by default. This would all go away.