Setting Account Picture/JPEGPhoto with dscl in terminal
Solution 1:
dscl
It seems that the most promising method is to modify the JPEGPhoto
attribute for the user. The problem is, while the JPEG image can be converted very simply to a hex string, the value is too long to just pass at the command-line. This attribute seems to be what the GUI writes to when you drag in an image. Recovering the image from this variable when set is as simple as:
dscl . read /Users/username JPEGPhoto | xxd -r -p > ./username.jpg
The second common way mentioned on the forums is to:
dscl . delete /Users/username JPEGPhoto
dscl . delete /Users/username Picture
dscl . delete /Users/username Picture "/Library/User Pictures/username.jpg"
This only changes the 'login' icon and not the icon seen in the User detail page in System Preferences.
Using dsimport
What does work for changing the user image is dsimport
.
The script usage is:
./change_userpic.sh USERNAME /path/to/image/jpg
GIST
#!/bin/bash
set -e
declare -x USERNAME="$1"
declare -x USERPIC="$2"
declare -r DSIMPORT_CMD="/usr/bin/dsimport"
declare -r ID_CMD="/usr/bin/id"
declare -r MAPPINGS='0x0A 0x5C 0x3A 0x2C'
declare -r ATTRS='dsRecTypeStandard:Users 2 dsAttrTypeStandard:RecordName externalbinary:dsAttrTypeStandard:JPEGPhoto'
if [ ! -f "${USERPIC}" ]; then
echo "User image required"
fi
# Check that the username exists - exit on error
${ID_CMD} "${USERNAME}" &>/dev/null || ( echo "User does not exist" && exit 1 )
declare -r PICIMPORT="$(mktemp /tmp/${USERNAME}_dsimport.XXXXXX)" || exit 1
printf "%s %s \n%s:%s" "${MAPPINGS}" "${ATTRS}" "${USERNAME}" "${USERPIC}" >"${PICIMPORT}"
${DSIMPORT_CMD} "${PICIMPORT}" /Local/Default M &&
echo "Successfully imported ${USERPIC} for ${USERNAME}."
rm "${PICIMPORT}"