Pretty much every script I’m working on these days must be run as root. Checking what user is running something is pretty straight forward, as there’s a built-in shell variable for $USER that contains the user running a script. To see this real quick, simply run the following:
You can then put this into your scripts. I’ve been using the same block of code for decades, which can be run in a script by itself if you’d like to paste this into one.
if [[ $USER != "root" ]]; then
echo "This script must be run as root"
echo "You are root"
Note: Keep in mind that the built-in $USER variable is case sensitive.
Obviously, most people won’t keep the lines that contain the else and you are root echo statements. You can just remove these or replace them with the meat of your script that requires elevated privileges to run. Enjoy.
krypted December 21st, 2015
I recently got my hands on one of those Google ChromeBooks (Cr-48). Interesting to have an operating system that is just a web browser. But, as anyone likely reading this article already knows, the graphical interface is the web browser and the operating system is still Linux. But what version? Well, let’s go on a journey together.
First, you need ChromeOS. If you’ve got a ChromeBook this is a pretty easy thing to get. If not, check http://getchrome.eu/download.php for a USB or optical download that can be run live (or even in a virtual machine). Or, if you know that you’re going to be using a virtual machine, consider a pre-built system from hexxeh at http://chromeos.hexxeh.net/vanilla.php. I have found the VMware builds to be a bit persnickety about the wireless on a Mac, whereas the VirtualBox builds ran perfectly. I split my time between the two anyway, so I’ve just (for now) been rocking VirtualBox for ChromeOS. When you load it for the first time it asks for a Google account. Provide that, select your network adapter, choose from one of the semi-lame account images ( for the record, I like the mad scientist one) and you’re off to the races.
Next, we need a shell. When you first log in, you see a web page that shows you all of the Chromium apps you have installed. By default, you’ll see File manager and Web Store. If you’ve used the OS X App Store then the Chrome Web Store is going to look pretty darn familiar. My favorite for now is Chrome Sniffer. But all of these kinda’ get away from where we’re trying to go: get a scripting environment for Chrome OS.
Chrome comes with 2 types of shell environments. The first is crosh. To bring up a crosh environment, use Control-Alt-t. This keystroke invokes the crosh shell. Here, type help to see a list of the commands available. Notice that cd, chmod, etc don’t work. Instead, there are a bunch of commands that a basic user environment might need for troubleshooting primarily network connections. “But this is Linux” you ask? Yup.
At the help output you’ll notice shell. Type shell and then hit enter. The prompt will change from crosh> to chronos@localhost. Now you can cd and perform other basic commands to your hearts delight. But you’re probably going to need to elevate privileges for the remainder of this exersize. So let’s type sudo bash and just get there for now. If you’re using a ChromeBook, the root password might be root, or if you’re using a downloaded vm from hexxeh then it might be facepunch (great password, btw).
Provided the password worked, the prompt should turn red. Now, if you’re using a hexxeh build then the file system is going to be read-only. You won’t be able to change the root password nor build scripts. But otherwise, you should be able to use passwd to change the password:
Once you’ve got slightly more secure shell environment (by virtue of not using the default root password), it is time to do a little exploring. Notice that in /bin, you see sh, bash, rbash and the standard fare of Linux commands (chmod, chown, cp, attr, etc. Notice that you don’t see tcsh, csh or ksh. So bash commands from other platforms can come in, but YMMV with tcsh, etc. Running ps will give you some idea of what’s going on process-wise under the hood:
From encrypts to crypto to the wpa supplicant, there’s plenty to get lost in exploring here, but as the title of the article suggests, we’re here to write a script. And where better to start than hello world. So let’s mkdir a /scripts directory:
Then let’s touch a script in there called helloworld.sh:
Then let’s give it the classic echo by opening it in a text editor (use vi as nano and pico aren’t there) and typing:
echo "Hello Cruel World"
Now close, save and then run it:
And you’ve done it. Use the exit command twice to get back to crosh and another time to close the command line screen. You now have a script running on ChromeOS. Next up, it’s time to start looking at deployment. This starts with knowing what you’re looking at. To see the kernel version:
Google has been kind enough to build in similar sandboxing to that in Mac OS X, but the concept that you can’t run local applications is a bit mistaken. Sure, the user interface is a web browser, but under the hood you can still do much of what most deployment engineers will need to do.
If these devices are to be deployed en masse at companies and schools, scripts that setup users, bind to LDAP (GCC isn’t built-in, so it might be a bit of a pain to get there), join networks and the such will need to be forthcoming. These don’t often come from the vendor of an operating system, but from the community that ends up supporting and owning the support. While the LDAP functionality could come from Google Apps accounts that are integrated with LDAP, the ability to have a “One touch deploy” is a necessity for any OS at scale, and until I start digging around for a few specific commands/frameworks and doing some deployment scripts to use them, right now I’m at about a 6 touch deploy… But all in good time!
krypted September 8th, 2011
Scripting directory services events is one of the most common ways that the OS X community automates post-imaging tasks. As such, there are about as many flavors of directory services scripts are there engineers that know both directory services and have a little scripting experience. In OS X Lion, many aspects of directory services change and bring with them new techniques for automation. The biggest change is the move from DirectoryService to opendirectoryd.
In Snow Leopard and below, when you performed certain tasks, you restarted the directory services daemon, DirectoryService. The same is true in Lion, except that instead of doing a killall on DirectoryService, you do it on opendirectoryd:
Also, local account passwords in OS X have been moved into attributes within user account property lists and so there is no longer a /var/db/shadow/hash directory. Therefore, copying property lists and their associated password hash file is no longer a necessary process.
dsperfmonitor vs odutil
Next, dsperfmonitor has gone to the great binary place in the sky to join dirt and DirectoryService. It is somewhat replaced with odutil. The odutil command is pretty easy and straight forward. You can see all open sessions, nodes, modules, requests, statistics and nodenames using the show verb (along with those subcommands). You can also set the logging level for directory services to alert, critical, error, warning, notice, info and debug, each with more and more events that are trapped. This is done with the set log verb along with the level (which is by default set to error):
odutil set log debug
The odutil command is also used to enable statistics. These are pretty memory intensive (or they were on a mini w/ 4GB of memory in it but might not be with your 32GB of RAM fortified Xserve). This is done using odutil’s set statistics verb w/ an option of either on or off:
odutil set statistics on
Note: It’s worth noticing that stats are persistent across restarts, so don’t forget to turn it off.
For Open Directory administrators, you’ll be elated to know that your LDAP bind script just got a bit shorter. Now, search policies are updated automatically when binding via dsconfigldap. But, if you have a bunch of scripting that you don’t want to rip apart you can still do search policies manually by using the spiffy new -S option for dsconfigldap (yes, I just insinuated that -S was for spiffy, what’s it to ya’?!?!).
scutil can now be used to view Active Directory Kerberos information. scutil can also be used to query the search node and interface states. klist no longer seems to function properly, so use ktutil to with a list verb to see service principals:
Not to be left out, the Active Directory binding tool, dsconfigad, got some new flair as well (yes, I just insinuated that dsconfigad was really Jennifer Aniston’s contribution to OS X and I challenge you to prove me wrong). There is now a -restrictDDNS option, which I’m sure you can guess disable dynamic DNS registration in Active Directory-integrated DNS zones. There’s also the rockin’ new -authority option, which enabls or disables Kerberos authority generation. Finally, dsconfigad gets some minor cosmetic changes. -f becomes -force, -r becomes -remove, -lu becomes -localuser, -lp becomes localpassword, -u becomes username, -p becomes -password, but the original options still work. Who knows how long the old operators will stick around, but my guess is they’ll be around until dsconfgad isn’t…
Most options and settings for the AD plug-in should now be configured following the AD bind process (thanks to @djstarr for that little addition). How does this impact your scripts. Just move the settings to the bottom of the script if they give you gruff… Also, the -enableSSO option has been changed to -enablesso.
Finally, defaults allows you to put the .plist in the command when you use a file path to list them out. This should eliminate the 6 backspaces we often had to type to test certain things after auto-completing file names… 🙂
krypted July 20th, 2011
I will go through long stretches without playing with new technology until I either get unbusy or get talked into figuring out how to do something remotely interesting with it. Like linking FaceTime up to a help desk database. It turns out that Apple made it a very straight forward process. Simply use a facetime handler as the prefix to a URL with the phone number of the other person (iPhone 4) or their FaceTime email address (usually with the desktop app).
For example, if my email were email@example.com then you could use the following from terminal:
Or if my phone number were 310-555-1212 (it is you know;):
krypted November 9th, 2010
Posted In: Mac OS X
Using Mac OS X, one of the most trivial things (provided you have permission) is to add an object to the dock. Applications go on the left side of the dock and folders/documents/stacks go on the right. From the command line it isn’t quite as trivial but not that complicated either. To do so from the command line, you can write directly into the com.apple.dock.plist for a user. To do so, we’re going to use the defaults command and we’re going to look at adding an application first:
defaults write com.apple.dock persistent-apps -array-add ‘<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>/Applications/Microsoft Office 2008/Microsoft Word</string><key>_CFURLStringType</key><integer>0</integer></dict></dict></dict>’
You can also add a custom title for the object that you are adding by using the file-label key and providing a string with the content that you want the label to have. You can also add a folder or file to the dock using a similar command:
defaults write com.apple.dock persistent-apps -array-add “<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>/Users</string><key>_CFURLStringType</key><integer>0</integer></dict><key>file-label</key><string>UsersDirectory</string><key>file-type</key><integer>18</integer></dict><key>tile-type</key><string>directory-tile</string></dict>”
You can also write an object using a variable, or another command when wrapped with “. For example, if we wanted to put a link to the specific users directory rather than the /Users directory we would use the following:
defaults write com.apple.dock persistent-apps -array-add “<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>/Users/`whoami`</string><key>_CFURLStringType</key><integer>0</integer></dict><key>file-label</key><string>MyHome</string><key>file-type</key><integer>18</integer></dict><key>tile-type</key><string>directory-tile</string></dict>”
There are several uses for this. For example, you can link to certain folders that allow you to access recently changed content. Provided you have mounted a network share you can also add a network directory, similar to what happens when you add your Network Home in managed preferences. But this gets the process started and from here it’s just figuring out your specific logic. Once you have added an item into the Dock you’ll then need to restart it:
You should then see your Dock item. It is worth noting that if the location does not exist then you will need to create it and so you might script some logic as such. Also, if you create the location after creating the item then you will need to restart the Dock again.
krypted August 2nd, 2010
One of those security things that pops up every now and then is to use the secure erase feature of Mac OS X, located in Disk Utility. But you can access this same feature from the command line using the secureErase option in diskutil followed by the freespace option.
The format of the command is:
diskutil secureErase freespace [level] [device]
The levels are as follows (per the man page as not all of these are specified in Disk Utility):
So for example, let’s say you had a volume called Seldon and you wanted to do a standard Single-pass zero-fill erase. In this example you would use the following:
diskutil secureErase freespace 0 /Volumes/Seldon
If you were to automate the command then you would want to dump the output into a log file. For example:
diskutil secureErase freespace 0 /Volumes/Seldon > /var/log/secureeraselog.tmp
krypted February 22nd, 2010
Posted In: Mac OS X
Let’s face it, connecting to Windows Servers is a must for many of us. And some of us want to do so programatically. I did look at populating the CoRD database in a previous article. But now, luckily CoRD has recently introduced a command line interface for managing just these types of connections on the fly as well. And, it is very straight forward.
There are two ways to call CoRD from the command line. The first is similar to how we handled VNC in an earlier article. Simply leverage the open command and call the URL with a rdp in the beginning. For example, if you want to open a connection to a server called windows.krypted.com you would use the following command:
As with VNC you can also inject he user name and the password as well. To do so insert the username after the rdp:// and with an @ before the domain or IP. And to inject the password follow the username with a : and then the password followed by the @. For example, if our username were daneel and our password were seldon then the command would be:
There are other options as well, which you can find at the CoRD Wiki. You can also connect by calling the CoRD command, which is located in the /Applications/CoRD.app/Contents/MacOS directory. The CoRD command then has the following options:
host – define the IP address or host name of the computer you are connecting to
port – if a custom port (not 3389) is used then use that to connect to the computer
u – define a username
p – define a password
d – Windows domain name
a – set screen depth to 8, 16, 24 or 32
width – set the width of the resultant window
height – set the height of the resultant window
So if you would like to connect to windows.krypted.com with the same user and password as before, but now with a custom port of 3390 you would use the following command:
/Applications/CoRD.app/Contents/MacOS/CoRD -host windows.krypted.com -port 3390 -u daneel -p seldon
I guess next I’m going to have to build a Dashboard widget to fire up a connection on the fly… 😉
krypted February 1st, 2010
My last article showed how to interface with the clipboard in Mac OS X. Windows 7 comes with the same feature, but instead of pbcopy it’s simply clip. Since you don’t ls, we’ll pipe the output of dir into the clipboard:
dir | clip
Enjoy & no more complaining that I like one platform more than the other – you know who you are!
krypted January 15th, 2010
Posted In: Windows XP
The new location options in networksetup are pretty interesting and while I’ve mentioned them in writings in the past I thought I would explore scripting against them, as they do reflect an interesting new challenge, mostly if you’re looking to script against non-booted volumes.
To script against a booted volume is fairly straight forward. You have the -listlocations, -getcurrentlocation, -createlocation, -deletelocation and -switchlocation options which lists all locations, lists the current location, creates a location, deletes a location and potentially switches a location. To get started, first look at what locations your system has:
If you are on a freshly installed system you should see Automatic as your only location. Therefore, that should be the output of the next option. But just to make sure, now use the -getcurrentlocation option to show your current location:
When you’re scripting the creation of locations you will use the -createlocation option. This option will allow you to create a new location without any network services created for that location. Let’s create an empty location called Work
networksetup -createlocation Work
This will create an entry in the /Library/Preferences/SystemConfiguration/preferences.plist. Each of these entries is marked with a unique identifier. That unique identifier is then referenced as a Set within the preferences.plist and as you create network services they are in turn referenced by a unique identifier within the set.
While we’re creating locations we can go ahead and create one with the default set of network services (1 of each physical adapter). To do so, use the -createlocation option again, but this time follow it with a populate verb. We’ll use this location to setup a location for home.
networksetup -createlocation Homeq populate
Oops, did we misspell Home as Homeq, we should probably delete that and create the one we actually meant to create. To do so use the -deletelocation option and then add the Home location again:
networksetup -deletelocation Homeq
The -deletelocation option will amusingly output the string found it!
networksetup -createlocation Home populate
Next, in order to configure the various network services within each location you will need to switch to that location. Here, we will switch the active location using the -switchlocation option:
networksetup -switchlocation Work
With the appropriate location selected, use the -createnetworkservice, -removenetworkservice and -ordernetworkservices options to more granularly configure your locations, as I previously covered.
krypted December 10th, 2009