├── .gitattributes ├── .gitignore ├── LICENSE.md ├── Makefile ├── README.md └── src └── uti.bash /.gitattributes: -------------------------------------------------------------------------------- 1 | Makefile linguist-detectable=false 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | uti 2 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2019 Read Evaluate Press, LLC 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a 4 | copy of this software and associated documentation files (the "Software"), 5 | to deal in the Software without restriction, including without limitation 6 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | and/or sell copies of the Software, and to permit persons to whom the 8 | Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 14 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | DEALINGS IN THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SHELL = /bin/bash 2 | 3 | prefix ?= /usr/local 4 | bindir ?= $(prefix)/bin 5 | srcdir = src 6 | 7 | .DEFAULT_GOAL = uti 8 | 9 | .PHONY: uti 10 | uti: $(srcdir)/uti.bash 11 | @cp $< $@ 12 | @chmod +x $@ 13 | 14 | .PHONY: check 15 | check: uti 16 | @set -e ; \ 17 | EXPECTED="public.data"; \ 18 | ACTUAL=$$(uti Makefile); \ 19 | if [ "$$EXPECTED" != "$$ACTUAL" ]; then \ 20 | echo "Expected: \"$$EXPECTED\"";\ 21 | echo "Actual: \"$$ACTUAL\""; \ 22 | exit 1; \ 23 | fi 24 | 25 | .PHONY: install 26 | install: uti 27 | @install -d "$(bindir)" 28 | @install uti "$(bindir)" 29 | 30 | .PHONY: uninstall 31 | uninstall: 32 | @rm -rf "$(bindir)/uti" 33 | 34 | .PHONY: clean 35 | clean: 36 | @rm -f uti 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # uti 2 | 3 | A command-line utility that prints the 4 | [Uniform Type Identifier](https://en.wikipedia.org/wiki/Uniform_Type_Identifier) 5 | for the files provided as an argument. 6 | 7 | ## Requirements 8 | 9 | - macOS 10.4+ 10 | 11 | ## Usage 12 | 13 | ```terminal 14 | $ uti Hello.swift 15 | public.swift-source 16 | ``` 17 | 18 | Results for multiple path arguments are printed on separate lines 19 | in the order they're provided: 20 | 21 | ```terminal 22 | $ uti index.html screen.css app.js 23 | public.html 24 | public.css 25 | com.netscape.javascript-source 26 | ``` 27 | 28 | If any of the provided file path arguments are invalid, 29 | the command exits with status code `1` 30 | and prints a message to standard error. 31 | 32 | ```terminal 33 | $ uti invalid 34 | error: invalid is not a file or directory 35 | ``` 36 | 37 | You can combine `uti` with other Unix commands. 38 | For example, 39 | to list the UTI for each file in a directory, 40 | you might invoke the `find` command like so: 41 | 42 | ```terminal 43 | $ ls . 44 | Xcode_11.xip 45 | Xcode.app 46 | 47 | $ find . -exec uti {} + 48 | com.apple.xip-archive 49 | com.apple.application-bundle 50 | ``` 51 | 52 | ## Installation 53 | 54 | ### Homebrew 55 | 56 | Run the following command to install using [homebrew](https://brew.sh/): 57 | 58 | ```terminal 59 | $ brew install nshipster/formulae/uti 60 | ``` 61 | 62 | ### Manually 63 | 64 | Run the following commands to build and install manually: 65 | 66 | ```terminal 67 | $ git clone https://github.com/NSHipster/uti.git 68 | $ cd uti 69 | $ make install 70 | ``` 71 | 72 | ## Additional Details 73 | 74 | `uti` delegates to the [`mdls`] system command, 75 | requesting the `kMDItemContentType` metadata attribute 76 | and processing the output. 77 | 78 | ## License 79 | 80 | MIT 81 | 82 | ## Contact 83 | 84 | Mattt ([@mattt](https://twitter.com/mattt)) 85 | 86 | [`mdls`]: https://www.unix.com/man-page/osx/1/mdls/ 87 | -------------------------------------------------------------------------------- /src/uti.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -r 4 | 5 | set -o errexit 6 | set -o pipefail 7 | set -o nounset 8 | 9 | if ! [ -x "$(command -v mdls)" ]; then 10 | echo 'error: mdls command not available.' >&2 11 | exit 1 12 | fi 13 | 14 | if [[ $# -eq 0 ]]; then 15 | echo 'usage: uti path [path...]' >&2 16 | exit 0 17 | fi 18 | 19 | for arg in "$@"; do 20 | if ! { [ -f "$arg" ] || [ -d "$arg" ]; }; then 21 | echo "error: $arg is not a file or directory" >&2 22 | exit 1 23 | fi 24 | done 25 | 26 | mdls -name kMDItemContentType "$@" | 27 | sed -E 's/kMDItemContentType = "(.+)"/\1/' 28 | --------------------------------------------------------------------------------