{"id":456,"date":"2012-03-13T13:19:58","date_gmt":"2012-03-13T18:19:58","guid":{"rendered":"http:\/\/www.brunerd.com\/blog\/?p=456"},"modified":"2023-01-06T13:53:55","modified_gmt":"2023-01-06T18:53:55","slug":"getting-and-setting-ppd-options-via-command-line-for-use-with-lpadmin-in-os-x","status":"publish","type":"post","link":"https:\/\/www.brunerd.com\/blog\/2012\/03\/13\/getting-and-setting-ppd-options-via-command-line-for-use-with-lpadmin-in-os-x\/","title":{"rendered":"Getting and setting PPD options via command line for use with lpadmin in OS X"},"content":{"rendered":"\n<p>UPDATE &#8211; Script now will&nbsp;convert CR to LF line endings for better reliability with old PPDs<\/p>\n\n\n\n<p>There are some good hints for adding printers via the command line with lpadmin: <a href=\"http:\/\/hints.macworld.com\/article.php?story=20061203221317612\">Managing multiple printers via the command line<\/a><\/p>\n\n\n\n<p>However, there is still confusion surrounding the setting of printer options from the command line, as a poster to Debian bugs pointed out back in 2006: <a href=\"http:\/\/bugs.debian.org\/cgi-bin\/bugreport.cgi?bug=381252\">lpoptions documentation doesn&#8217;t<\/a>. After doing some testing, here&#8217;s the two main takewaways:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>If you use lpadmin and specify options with &#8220;-o&#8221; the PPD is altered and OS X will recognize the options for the printer.<\/li>\n\n\n\n<li>However, if you setup the printer using lpadmin without any options and later use lptoptions to set the options, they are not written to the PPD and the GUI is unaware of the printer&#8217;s options.<\/li>\n<\/ul>\n\n\n\n<p><strong style=\"color: #444444; font-family: Georgia, 'Bitstream Charter', serif; font-size: 16px; line-height: 24px;\">more helpful hints about lpadmin and lpoptions:<\/strong><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>lpoptions -p <em>printername<\/em> -l<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Prints PPD options, &#8220;Default&#8221; is filtered out from option name (compared to looking at the raw PPD)<\/li>\n\n\n\n<li>It uses a colon when reporting key value pairs, however replace that with an equals sign when specifying an option<\/li>\n\n\n\n<li>The option name stops at the first slash<\/li>\n\n\n\n<li><strong>Example:<\/strong> The duplex option for HP printers will output like this &#8220;HPOption_Duplexer\/Duplex Unit: *True False&#8221;<br>When specified as a &#8220;-o&#8221; option it would be &#8220;HPOption_Duplexer=True&#8221;<\/li>\n<\/ul>\n\n\n\n<p><strong>lpadmin &#8230; -o this=that<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Alters the ppd that is placed in \/etc\/cups\/ppd\/ when the printer is installed<\/li>\n<\/ul>\n\n\n\n<p><strong>Unhelpful things:<\/strong><\/p>\n\n\n\n<p><strong>lpoptions -p printername<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>These are NOT the PPD options you want to set<\/li>\n<\/ul>\n\n\n\n<p><span class=\"Apple-style-span\" style=\"font-size: 16px; color: #444444; font-family: Georgia, 'Bitstream Charter', serif; line-height: 24px;\"><strong>lpoptions -o<\/strong><\/span><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Only writes options to: <em>\/private\/etc\/cups\/lpoptions<\/em> (run with sudo) or <em>~\/.cups\/lpoptions<\/em> (run as current user), GUI apps are unaware of these options<\/li>\n<\/ul>\n\n\n\n<p><span class=\"Apple-style-span\" style=\"font-size: 16px; color: #444444; font-family: Georgia, 'Bitstream Charter', serif; line-height: 24px;\"><br>The following script compares the original and the newly installed PPD to generate the options syntax to be used with lpadmin:&nbsp;<\/span><\/p>\n<\/blockquote>\n\n\n\n<p>The main magic in this script is a little diff and sed:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><code>diff \"$originalfile\" \"$newfile\" | grep \"&gt; [*]Default\" | sed 's\/&gt; [*]Default\/-o \/g' | sed 's\/: \/=\/g'<\/code><\/p>\n<\/blockquote>\n\n\n\n<p><strong>Script Workflow<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Copy and paste the script into <a href=\"http:\/\/barebones.com\/products\/textwrangler\/\">TextWrangler<\/a>&nbsp;(or download <a href=\"http:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/ppdOptionsDiff.command.zip\">ppdOptionsDiff.command<\/a>), save with a .command extension and it will automatically take care of the executable bit<\/li>\n\n\n\n<li>Setup your printer via the Printers Preference Pane in the GUI.<\/li>\n\n\n\n<li>Look in \/etc\/cups\/ppd and find the newest .ppd (it will be named as the printer)<\/li>\n\n\n\n<li>Locate the original .ppd.gz (or .ppd) in \/Library\/Printers\/PPDs\/Contents\/Resources\/, usually the printer ppd is easily found by name, but some like Canon have some cryptic filenames, so look inside the \/etc\/cup\/ppd file, the &#8220;PCFileName&#8221; variable sometimes helps to determine the file name<\/li>\n\n\n\n<li>Run the script given below, it will ask you to drag in the original and the modified ppds. Out will come the &#8220;-o&#8221; options for use with lpadmin<\/li>\n<\/ul>\n\n\n\n<p><span class=\"Apple-style-span\" style=\"font-size: 16px; color: #444444; font-family: Georgia, 'Bitstream Charter', serif; line-height: 24px;\">You can also run the script with the original and modified file paths as arguments and the string will be output<\/span><\/p>\n\n\n\n<p><strong>The script &#8220;<a href=\"http:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/ppdOptionsDiff.command.zip\">ppdOptionsDiff.command<\/a>&#8220;:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code language-bash\"><code>#!\/bin\/bash\n&#91; -f \/tmp\/debug ] &amp;&amp; set -x\n#ppd option maker\n\n#help\nif &#91; \"$1\" == \"-h\" ]; then\n\techo \"$(basename $0) compares two ppds and outputs the differences as a string for use in lpadmin\"\n\techo \"Usage: $(basename $0) &#91;original_ppd] &#91;new_ppd]\"\n\texit\nfi\n\n#check for parameter if not ask\nif &#91; -z \"$1\" -o -z \"$2\" ]; then\n\tclear;\n\techo \"Drag in the unmodified PPD from \/Library\/Printers\/PPDs\/Contents\/Resources:\"\n\topen \/Library\/Printers\/PPDs\/Contents\/Resources\n\twhile &#91; -z \"$originalfile\" ]; do\n\tread originalfile\n\tdone\n\n\techo \"Drag in the PPD from \/etc\/cups\/ppd:\"\n\topen \/etc\/cups\/ppd\n\twhile &#91; -z \"$newfile\" ]; do\n\tread newfile\n\tdone\n#else just take the arguments\nelif &#91; -n \"$1\" -o -n \"$2\" ]; then\n\tnewfile=\"$2\"\n\toriginalfile=\"$1\"\nfi\n\n#make a temp file of the original to compare\n#strip off path and extension for temp file name\ntempOriginalFile=\"\/tmp\/$(basename \"$originalfile\" .gz)\"\n\n#if file is compressed expand\nif &#91; \"${originalfile##*.}\" == \"gz\" ]; then\n\t#uncompress\n\tIFS=$'\\n\\t'\n\t#gunzip to temp file\n\tgunzip &lt; \"$originalfile\" > \"$tempOriginalFile\"\nelse\n#just make a copy\ncp \"$originalfile\" \"$tempOriginalFile\"\nfi\n\n#change line endings from CR to LF (diff fails unless this is done)\nsed -e $'s\/\\\\\\r\/\\\\\\n\/g' -i '' \"$tempOriginalFile\"\n\n#make a temp file of the new file to compare\n#strip off path\ntempNewFile=\"\/tmp\/$(basename \"$newfile\")\"\ncp \"$newfile\" \"$tempNewFile\"\n\n#change line endings from CR to LF (diff fails unless this is done)\nsed -e $'s\/\\\\\\r\/\\\\\\n\/g' -i '' \"$tempNewFile\"\n\n#test for file existence\nif &#91; ! -f \"$tempOriginalFile\" ]; then echo \"$tempOriginalFile is not a valid path\"; exit; fi \nif &#91; ! -f \"$tempNewFile\" ]; then echo \"$tempNewFile is not a valid path\"; exit; fi \n\n#create options list by diffing and filtering\noptionList=$(diff \"$tempOriginalFile\" \"$tempNewFile\" | grep \"> &#91;*]Default\" | sed 's\/> &#91;*]Default\/-o \/g' | sed 's\/: \/=\/g')\n\n#print out the options with no line breaks\nIFS=$'\\n\\t'\nif &#91; ! -z \"$optionList\" ]; then\n\tfor option in $optionList; do \n\t\techo -n \"$option \"\n\tdone\n\techo\nelse\n\techo \"No differences\"\nfi\n\n#delete the temp filess\nrm \"$tempOriginalFile\" \"$tempNewFile\"\n\nexit<\/code><\/pre>\n\n\n\n<p><span class=\"Apple-style-span\" style=\"font-size: 16px; color: #444444; font-family: Georgia, 'Bitstream Charter', serif; line-height: 24px;\"> <strong>Example<\/strong> (with pathnames provided as arguments, otherwise runs in interactive mode)<strong>:<\/strong><\/span><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>$ .\/ppdOptionsDiff.command \/Library\/Printers\/PPDs\/Contents\/Resources\/HP\\ LaserJet\\ 5200.gz \/private\/etc\/cups\/ppd\/PRINTERNAME.ppd<\/p>\n\n\n\n<p><strong>-o HPOption_Tray3=Tray3_500 -o HPCollateSupported=True -o HPOption_Duplexer=True -o HPOption_Disk=RAMDisk<\/strong><\/p>\n<\/blockquote>\n\n\n\n<p>Use the generated string in lpadmin to set the printer options, like this example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>lpadmin -p \"Ye_Olde_LaserJet\" -D \"Ye Olde LaserJet\" -E -v socket:\/\/x.x.x.x -P \/Library\/Printers\/PPDs\/Contents\/Resources\/HP\\ LaserJet\\ 5200.gz -L \"Location is in a closet in a sub-basement, good luck\" -D -o HPOption_Tray3=Tray3_500 -o HPCollateSupported=True -o HPOption_Duplexer=True -o HPOption_Disk=RAMDisk -o printer-is-shared=false<\/code><\/pre>\n\n\n\n<p>The documentation from  <code>man lpadmin<\/code> is a bit obtuse and lacking. For example: <code>-E<\/code> will enable the printer (essential!) <em>except<\/em> when used <em>before<\/em> <code>-p<\/code> or <code>-d<\/code> in those cases it forces encryption, so watch out! Also, in the man page it shows <code>-h server[:port]<\/code> but <code>-h<\/code> is not documented anywhere in there and I have <em>never<\/em> used it. Rather, the <code>-v<\/code> option should be used with a URL like <code>lpd:\/\/<\/code>, <code>socket:\/\/<\/code> (HP), <code>ipp:\/\/<\/code>, etc.. if you want to get a listing of the protocols run <code>lpinfo -v<\/code> this will even do a look around with Bonjour to see what&#8217;s on the network (they are <code>dnssd:\/\/<\/code>). The <code>-p<\/code> option is the CUPS queue name, it does <em>not<\/em> allow spaces, whereas the <code>-D<\/code> option is the &#8220;friendly name&#8221; that a user will see in macOS, you  can set some location text with <code>-L<\/code> and finally just tack all the <code>-o<\/code> options on the end. <code>-o printer-is-shared=false<\/code> will keep the printer from being broadcast if you turn on Printer Sharing (or if a user <em>accidentally<\/em> turns it on)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>UPDATE &#8211; Script now will&nbsp;convert CR to LF line endings for better reliability with old PPDs There are some good hints for adding printers via the command line with lpadmin: Managing multiple printers via the command line However, there is still confusion surrounding the setting of printer options from the command line, as a poster [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,4,12],"tags":[],"class_list":["post-456","post","type-post","status-publish","format-standard","hentry","category-apple","category-os-x","category-scripting"],"_links":{"self":[{"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/posts\/456","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/comments?post=456"}],"version-history":[{"count":9,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/posts\/456\/revisions"}],"predecessor-version":[{"id":1362,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/posts\/456\/revisions\/1362"}],"wp:attachment":[{"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/media?parent=456"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/categories?post=456"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/tags?post=456"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}