krypted.com

Tiny Deathstars of Foulness

One of my favorite things about grabbing things with scripts is just how many ways (and sometimes how needfully or needlessly convoluted you can make them) to grab the same pieces of information. For example, something as simple as what hosts you use to resolve names on a Mac. There are a number of ways to grab what DNS server a device is using in macOS. So when you’re running a script you might choose to grab DNS information one way or another, according to what you’re after. Some of this might seem more complicated than it should be. And that’s correct…

resolv.conf

The /etc/resolv.conf file is updated automatically to look at what servers are used to resolve names used for DNS. The easiest way to see theses to simply cat it and grep for nameserver:

cat /etc/resolv.conf | grep nameserver

scutil

The next way we’ll grab DNS information is using scutil. Here, we use the –dns option, which outputs a lot of DNS stuffs, including all the built-in resolvers:

scutil --dns

To just grab the name servers:

scutil --dns | grep nameserver

We can also simplify the output to just the servers with awk:

scutil --dns | grep nameserver | awk '{print$3}'

networksetup

The second way is using networksetup. This command has an option to get a DNS server in (shocker) -getdnsservers. However, you have to list the interface for each. So below we’ll dump all interfaces into an array using -listallhardwareports and then read them in using a for loop and querying the name servers.

interfaces=( "$(networksetup -listallhardwareports | grep Hardware | cut -c 16-900)" )
for i in "${interfaces[@]}"
do
networksetup -getdnsservers $i
done

The one tricky thing in this one is I initially forgot to quote the interfaces as they went into the array, which meant each word of the interface was an item in the array and therefore the -getdnsservers option failed. Once I quoted, it was all happy. The other thing I can point out is I used cut instead of sed because it was easier to quote; however, it seems unlikely the name can be more than 890 characters, so I think it’s fine…

dig

You can also use dig. Here, you’ll query for a name without using an @ option, but omit everything but the line with the server that responded:

dig google.com | grep SERVER:

The output is kinda’ fug:

;; SERVER: 4.2.2.2#53(4.2.2.2)

For simpler output, we’ll use sed to constrain the output to just what’s between the parenthesis:

dig google.com | grep SERVER: | sed 's/^.*(//;s/)$//'

nslookup

nslookup is a tool similar to dig, used for querying names. We’ll basically do the same thing as above, just using awk as it’s just a standard position in a line:

nslookup google.com | grep Server: | awk '{print$2}'

system_profiler

Then there’s system_profiler, the command line interface for System Profiler. Here, we can query the SPNetworkDataType. This is going to produce a lot of output, so we can limit it to just the DNS servers using grep to constrain to just the lines we want and awk for just the columns in those lines, as follows:

system_profiler SPNetworkDataType | grep "Domain Name Servers:" | awk '{print$4}'

hosts

@knapjack added to use hosts. I had to use verbose mode to pull the local name server as follows:

host -v -t ns google.com | grep Received | awk '{print $5}'

ipconfig

Thanks to the lovely Allister (@sacrilicious), we also have ipconfig to add to the list:

/usr/sbin/ipconfig getpacket en0 2> /dev/null | grep name_ | cut -d' ' -f3-

There are tons of ways to find things in macOS. Do you have a way to find a DNS server that I didn’t think of here?

March 6th, 2017

Posted In: bash, Mac OS X, Mac OS X Server, Mac Security, Ubuntu

Tags: , , , , , , ,

4 Comments

There’s a great site out there called spellcheck.net that will check your bash scripts to verify that they are syntactically correct and offer some tips on fixing issues you may encounter. In the example below, I single quoted at the end of a quoted string, and… error
screen-shot-2016-12-14-at-9-44-00-am
Hat tip to Daniel MacLaughlin for posting this site.

December 14th, 2016

Posted In: Programming, Ubuntu

Given the increased reliance on XML in scripts and exchanging data, a number of different solutions leverage XML traversal options to get all the things done. We frequently use path to bring a file into a script or program, or accept input from STDIN. The most basic task that we then perform is simply selecting an item from that file or STDIN and then variabalizing it. One common tool that we use here is Path. XPath calls these objects nodes, and uses path expressions to select these nodes. A path expression is the path along the xml input that is followed to find a piece of data.

There are some pretty standard wildcards the can be used with xpath, where node() watches any node, * matches any element node, @* matches any attribute node, helping to constrain output.

Supported expressions include:

  • node: This is a text input that identifies the name of a node to start a relative search from – for example site would select all nodes in a structure with the name site
  • . Identifies the current node (kinda’ like pwd in a shell)
  • .. Starts at the parent of the current node – for example,
  • / Starts traversal from the root node – for example, /computer would select any nodes that falls underneath
  • /computer meaning that these are absolute paths
  • // Identifies the nodes in an XML structure that match a selection wherever they may be – for example
  • //computer would select all nodes that contain //computer and search for other expressions below those that you may identify such as: ‘xpath //computer/general/mac_address’
  • //* Selects everything
  • //computer/* Selects all the child element nodes of everything that starts with computer
  • @ Select an attribute in an XML structure – for example ‘xpath //computer/general/@’
  • [1] This predicate selects the first item (or whatever number is identified, so xpath
  • //computer[3]/general/mac_address would return with the mac address of the third computer
  • [@PATTERN] Constrains found sets, so ‘xpath //computer/general/[@mac_address]’ identifies all computers with an actual mac_address attribute
  • //[@PATTERN=VALUE] Constrains a found set to all items where the attribute contains the value, so ‘xpath //computer/general/[@mac_address=00]’ identifies all computers with an actual mac_address attribute that has the value of 00
  • //[@*] Selects only items with something in an attribute (non-null), so ‘xpath //computer/general/[@mac_address=@*] (btw, rather than use an =, you can use > or <)
  • | creates compound matches. So ‘xpath //computer/general/mac_address | //computer/general/name’ would grab the mac_address and name of every computer
  • [last()] Identifies the last item, so ‘xpath //computer[last()]/general/mac_address’ would return the last computer’s mac address
  • [last()-2] placing a negative number after the parenthesis identifies descending orders from the end of a found set – for example, //computer[last()-2] Selects the second to last computer

Overall, as you can see xpath really makes traversing XML structures simple. Other tools and languages have their own ways, but most are similar in syntax.

November 15th, 2016

Posted In: Mac OS X, Mac OS X Server, Ubuntu

Tags: , , , , ,

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:

Screen Shot 2016-04-16 at 11.21.48 PM

Then, throw out a bash command followed by < and then the URL you just copied into your clipboard in parenthesis:

bash <(curl -Ls https://github.com/krypted/resetsoftwareupdate/raw/master/resetsoftwareupdate.sh)

April 20th, 2016

Posted In: Mac OS X, Mac OS X Server, Mac Security, Ubuntu, Unix

Tags: , , , ,

August 29th, 2015

Posted In: Mac OS X, Ubuntu, Unix

By default, the Chromium OS rootfs is read-only. If you boot the system in developer mode, you will be able to disable rootfs verification and modify existing files or write new files into the file system. Before you do this, note that your file system will no longer be verifiable (won’t checksum properly) and you’ll end up needing to restore a recovery image in order to get back to normal mode. So this might be a bit dangerous if you’re not using the device for something like regression analysis (why I needed to do this).

To make the file system writeable, first fire up a command prompt via crosh, by using Control-Alt-T and then running the shell command at the shell prompt:

shell

Then run the following shell script to remote rootfs verification and make the file system writeable:

sudo /usr/share/vboot/bin/make_dev_ssd.sh --remove_rootfs_verification

 

Then you can reboot and do whatever it is you need to do. For example, install a vine server and run automation scripts to do regression testing. Enjoy.

August 18th, 2015

Posted In: ChromeOS, Ubuntu, Unix

Tags: , , , ,

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:

history

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:

fc -l

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:

fc

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.

August 14th, 2015

Posted In: Mac OS X, Mac OS X Server, Mac Security, Mass Deployment, Ubuntu, Unix

Tags: , , , , , , , ,

Earlier, we looked at creating thousands of empty directories. Today, we’re going to get rid of them. But we need to get rid of only empty directories. To do so, we’ll use the find command:

find . -depth -type d -empty -exec rmdir {} \;

Now, we can put both into a script:

mkdir $(printf '%05d\n' {1..10000})
find . -depth -type d -empty -exec rmdir {} \;

July 29th, 2015

Posted In: Mac OS X, Ubuntu, Unix

Tags: , , , ,

You can easily accept user provided input in bash by using the read command in bash for Linux and OS X. Here, we’ll echo out a choice to a user in a script, read the output into a variable called yn and then echo out the response:

echo "Please enter y or n: "
read yn
echo "You chose wrong: $yn"

Here, we used echo to simply write out what was chosen in the input. But we could also take this a little further and leverage a case statement to then run an action based on the choice selected:

read -p "Should the file extension change warning be disabled (y/n)? " yn
case ${yn:0:1} in
y|Y )
defaults write com.apple.finder FXEnableExtensionChangeWarning -bool false
echo "The warning has been disabled"
;;
* )
defaults write com.apple.finder FXEnableExtensionChangeWarning -bool true
echo "The warning has been enabled"
;;
esac

The options when scripting are pretty much infinite and chances are, if you’ve written any scripts, you’ll know of a better way to do this than how I’ve always done it. One of the great things about scripting is the fact that there’s always a better way. So feel free to throw any of your examples into the comments!

July 28th, 2015

Posted In: Mac OS X, Mac OS X Server, Mac Security, Ubuntu, Unix

Tags: , , , , , , , ,

Sometimes when I’m writing a script, I need something to phone home to something in the script. For example, this can tell another daemon where to ssh into when I invoke it remotely. So, let’s say I want to grab my WAN address in a script. I can use curl with a number of 3rd party sites (sites that often change. But, one that we can use here is ipecho.net. Here, we’ll look at their plain output page here:

curl ipecho.net/plain

This can then get output into a variable or file for processing in other parts of a script. For example, the output here is basically the same thing but the command is in backticks, as you might put it in when scripting:

echo `curl ipecho.net/plain`

July 26th, 2015

Posted In: Mac OS X, Mac OS X Server, Mac Security, Ubuntu, Unix

Tags: , ,

Next Page »