Dropping network connections can be incredibly frustrating. And finding the source can be a challenge. Over the years, I’ve found a number of troubleshooting methods, but the intermittent drop can be the worse to troubleshoot around. When this happens, I’ve occasionally resorted to scripting around failures, and dumping information into a log file to find the issue. For example, you may find that when a network connection fails, you have a very strong signal somewhere, or that you have a very weak signal on all networks.
I’ve found there are three pretty simple commands to test joining/unjoining, and using networks (beyond the standard pings or port scans on hosts). The first is the airport command, along with –disassociate. This just unjoins all networks:
sudo /System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport --disassociate
The second is a quick scan. Here, I’ve grep’d out the network I’m after (aka SSIDofNetwork – a very likely wireless network name), but when looking for environmental issues, you might choose to parse this into a csv and output all networks:
sudo /System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -s | grep SSIDofNetwork
Finally, you can join a network. You might have to escape out special characters in a password and it’s never wise to put a password into a script, etc. But, quick and dirty, this will join that SSIDofNetwork network:
sudo networksetup -setairportnetwork en0 "SSIDofNetwork" mysecretpassword
Anyway, loop it, invoke it however you invoke it, etc. Hope this helps someone, and if you have other tricks you’ve found helpful, feel free to throw them in the ‘ole comments!
There are a lot of scripts stored on github. And you can run them directly by curling them into bash. To do so, you’ll need a link to the raw script (using the github page with the URL of the script brings in all the cruft, so you’ll need to find the raw text). To grab that, click on the page with the script and then right-click on Raw, as seen here:
Then, throw out a bash command followed by < and then the URL you just copied into your clipboard in parenthesis:
When I’m working on a little bash script, I’ll often make a backup, each time I save and test. Then I can revert back, if I need to. The syntax I’ll use is to cp and then curly-bracket the output into .bak files (that’s a 90s era file extension I use for such nonsense):
So if I’m writing a script called MYSCRIPT.sh:
The resultant backup of the script is MYSCRIPT.sh.bak.
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"
fiNote: 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.
We tend to use a lot of commands in the Terminal app. That is, after all, what it’s there fore. And there’s a nice history of what we do. There are also a number of ways to view and manage the bash history. The simplest of which is the history command, which will show the previous commands run. Here, we’ll simply run it:
Keep in mind that this shows the history based on context, so if you sudo bash, you’ll potentially see a different history. You can also use the bash built-in fc command, which has the additional awesomeness of being able to edit and re-run commands from the history. To start, we’ll simply look at showing the last 16 commands using the -l option:
You can also constraint entries in the output by specific line numbers. For example, to see lines 12 through 18, simply use them as the first two positions of the command after fc:
fc 12 18
You can load the history into an editor and remove or add entries using fc without any options:
To exit the editor, hit control-z. I’ve written in the past about using substitution. For example, sudo !! to run the last command. fc can do some basic substitution as well. For example, use the -s to start substation and then enter a string, which will append whatever you like before a command. So the following would put sudo in front and re-run the previous command:
fc -s sudo
And let’s say that you were doing a find for a string of krypted. To then swap that string with charles:
fc -s krypted=charles
Overall, the bash history can be incredibly useful. I frequently pipe the output of a series of lines into a new file with a .sh at the end as a starting point for scripts and use these substitution options to save myself a bunch of time not retyping longer commands. Enjoy.
The cd command has lots of fun little shortcuts. One I use frequently is the -. The ~ always takes you to your home directory, but using cd – will take you to the last directory you were in. For example, if you do the following on a Mac:
Then you do .. (which is a shortcut for the directory above the one you’re in):
Then pwd will show that you’re in /Users. But, if you cd to – again:
Now you’re back in your home folder. The – expands to OLDPWD. Quick tip. Nothing more to see here.
The options for Open Directory continue to get more refined, aligning with opendirectoryd. The odutil command is becoming more and more useful with each version of OS X. Let’s inspect the directory service cache, using odutil with the show verb and the cache option:
odutil show cache
You can also view statistics for opendirectoryd using that show verb but with the statistics option:
odutil show statistics
And to see everything, use odutil with the show verb and the all option to get plenty of data to grep through:
odutil show all
The final show option we’ll look at is configuration. Here, you will also need to feed a directory nodename into the command:
odutil show configuration /Search
Now, /Search is a node but there are a lot. You can use show with nodes to see a listing of all the nodes:
odutil show nodes
You can then see which pids have references to opendirectoryd as well as the nodenames, reference IDs, and session IDs.
All of this can be very helpful when troubleshooting Open Directory issues. One thing I find I do pretty frequently is resetting statistics then repeating a process that is causing a problem so I can view only the updated statistics. To do so:
odutil reset statistics
You can also disable statistics (I’ve seen them create performance concerns:
odutil set statistics off
Or to turn them back on:
odutil set statistics on
Once upon a time you could killall DirectoryService with a -usr level to set various logging levels. With opendirectoryd, we can still do that, but it’s less cludgy with odutil. Here, we’ll set the logging level as detailed as we can get:
odutil set log debug
Other levels, in ascending order of verbosity, include alert, critical, error, warning, notice, and info.
When you run a kill command to stop a process from bash or the javax.realtime.POSIXSignalHandler class, you’re sending what’s known as a POSIX signal to the process. These signals can be called via their numeric representations or the signal (e.g. with the -s option of the kill command). Signals include the following:
1: SIGHUP – Close the controlling terminal when the controlling process dies
2: SIGINT – Send a keyboard interrupt
3: SIGQUIT – Quit from a keyboard/terminal
4: SIGILL – Terminate illegal instruction with a core dump and don’t restart
5: SIGTRAP – Send a trace/break trap (with core dump)
6: SIGABRT – Process an abort signal
7: SIGEMT – Send the signal when emulator traps happen
8:SIGFPE – Terminate floating point errors (erroneous arithmetic operations) with a core dump
9: SIGKILL – Kill a signal outright (kill cannot be ignored)
10: SIGBUS – Terminate access (some portion of a memory object) with a core dump
11: SIGSEGV – Terminate with a core dump – Invalid memory reference
12: SIGSYS – Bad system call
13: SIGPIPE – Terminate and write on the pipe
14: SIGALRM – Timed kill of a signal
15: SIGTERM – Software termination of a signal
16: SIGUSR1 – User defined signal 1, with SIGUSR2 as user defined signal 2
17: SIGTERM – Software termination of a signal
18: SIGCHLD – Child status change
19: SIGPWR – Send the signal when the system encounters a power failure
20: SIGWINCH – Send the signal to a process when the window changes
21: SIGURG – Ignore signal, high bandwidth data
22: SIGIO – Terminate pollable event
23: SIGSTOP – Stop executing (cannot be ignored or caught by an exception)
24: SIGTSTP – Terminate a stop signal.
25: SIGCONT – If stopped, continue executing a process
26: SIGTTIN – Background process is attempting to read
27: SIGTTOU – Background process is attempting to write
28: SIGVTALTM – Expired virtual timer
29: SIGPROF – Terminate Profiling timer
30: SIGXCPU – Past the CPU time limit, terminate with a core dump
31: SIGXFSZ – Past the file size limit, terminate with a core dump
32: SIGWAITING – Suspend execution of the process until a defined signal is sent
33: SIGLWP – Send when the implementing threading requires a signal
34: SIGFREEZE – Deprecated
35: SIGTHAW – Deprecated
36: SIGCANCEL – Deprecated
37: SIGLOST – Send the signal when encountering a lost file lock
To put these in practice, let’s use the kill command from bash, with the -s option followed by SIGTERM and then the pid number:
sudo kill -s SIGTERM 20341