{"id":2872,"date":"2019-01-06T16:01:20","date_gmt":"2019-01-06T21:01:20","guid":{"rendered":"http:\/\/osric.com\/chris\/accidental-developer\/?p=2872"},"modified":"2019-01-06T16:01:20","modified_gmt":"2019-01-06T21:01:20","slug":"cp-mv-ownership-attributes","status":"publish","type":"post","link":"https:\/\/osric.com\/chris\/accidental-developer\/2019\/01\/cp-mv-ownership-attributes\/","title":{"rendered":"cp, mv, ownership and attributes"},"content":{"rendered":"<p>I had always been under the impressions that when moving a file from one Linux filesystem to another (i.e. a new inode is created), that <code>mv<\/code> is essentially a <code>cp<\/code> command followed by an <code>rm<\/code> command.<\/p>\n<p>That&#8217;s not quite correct. It is essentially a <code>cp --archive<\/code> command followed by an <code>rm<\/code> command.<br \/>\n<!--more--><\/p>\n<p><strong>The difference between moving a file and copying a file<\/strong><\/p>\n<p>Moving a file preserves the ownership and existing file attributes, including the SELinux file type context. In the example case below, you can see that moving a file keeps the owner (<code>chris<\/code>) and the SELinux context of the directory in which the file was created (<code>user_home_t<\/code>).<\/p>\n<p>A copied file inherits the properties, including the SELinux type context, of its parent directory.<\/p>\n<p>Here&#8217;s a demonstration of the difference:<\/p>\n<p><strong>Create and move a file<\/strong><\/p>\n<pre><code>$ touch test\r\n$ ls -lZ test\r\n-rw-r-----. chris chris unconfined_u:object_r:user_home_t:s0 test\r\n\r\n$ sudo mv test \/usr\/local\/bin\/\r\n$ ls -lZ \/usr\/local\/bin\/test \r\n-rw-r-----. chris chris unconfined_u:object_r:user_home_t:s0 \/usr\/local\/bin\/test\r\n\r\n$ sudo rm \/usr\/local\/bin\/test<\/code><\/pre>\n<p><strong>Create and copy a file<\/strong><\/p>\n<pre><code>$ touch test\r\n$ ls -lZ test\r\n-rw-r-----. chris chris unconfined_u:object_r:user_home_t:s0 test\r\n\r\n$ sudo cp test \/usr\/local\/bin\/\r\n$ ls -lZ \/usr\/local\/bin\/test \r\n-rw-r-----. root root unconfined_u:object_r:bin_t:s0   \/usr\/local\/bin\/test<\/code><\/pre>\n<p>The copy of the file has a new owner, and a new SELinux context. Note there is an option (<code>mv -Z<\/code>) to reset the SELinux context when moving a file, but it would still maintain the original owner\/group.<\/p>\n<p><strong>What does the documentation say?<\/strong><\/p>\n<p><code>man cp<\/code> and <code>man mv<\/code> both directed me to the coreutils documentation for the complete manual. Some of the more relevant excerpts I have included below:<\/p>\n<blockquote><p>It first uses some of the same code that&#8217;s used by &#8216;cp -a&#8217; to copy the requested directories and files, then (assuming the copy succeeded) it removes the originals.<\/p><\/blockquote>\n<p>(From <code>info coreutils 'mv invocation'<\/code>)<\/p>\n<blockquote><p>&#8216;mv&#8217; always tries to copy extended attributes (xattr), which may include SELinux context, ACLs or Capabilities.  Upon failure all but &#8216;Operation not supported&#8217; warnings are output.<\/p><\/blockquote>\n<p>(From <code>info coreutils 'mv invocation'<\/code>)<\/p>\n<p>So what is <code>cp -a<\/code>?<\/p>\n<blockquote><p>&#8216;-a&#8217;<br \/>\n&#8216;&#8211;archive&#8217;<br \/>\nPreserve as much as possible of the structure and attributes of the original files in the copy (but do not attempt to preserve internal directory structure; i.e., &#8216;ls -U&#8217; may list the entries in a copied directory in a different order).  Try to preserve SELinux security context and extended attributes (xattr), but ignore any failure to do that and print no corresponding diagnostic.  Equivalent to &#8216;-dR &#8211;preserve=all&#8217; with the reduced diagnostics.<\/p><\/blockquote>\n<p>(From <code>info coreutils 'cp invocation'<\/code>)<\/p>\n<p>Which leads us to <code>--preserve=all<\/code>:<\/p>\n<blockquote><p>&#8216;-p&#8217;<br \/>\n&#8221;&#8211;preserve'[=ATTRIBUTE_LIST]&#8217;<br \/>\nPreserve the specified attributes of the original files.  If specified, the ATTRIBUTE_LIST must be a comma-separated list of one or more of the following strings:<\/p><\/blockquote>\n<p>(From <code>info coreutils 'cp invocation'<\/code>)<\/p>\n<p>Those attributes include, among others, <code>ownership<\/code>, <code>context<\/code> (SELinux context), and <code>all<\/code>.<\/p>\n<p><strong>Summary<\/strong><br \/>\nA <code>mv<\/code> command, across filesystems, is still essentially a <code>cp<\/code> command followed by an <code>rm<\/code> command, but with <code>--archive<\/code> flag specified for the <code>cp<\/code> command. If you encounter unexpected problems after moving a file, double-check the file&#8217;s ownership, attributes, and SELinux context.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;d always hear that mv is basically a cp followed by an rm. That&#8217;s mostly true, but mv uses a cp command with some optional flags to preserve ownership, attributes, and SELinux context. <\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[458],"class_list":["post-2872","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-selinux"],"_links":{"self":[{"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/posts\/2872","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/comments?post=2872"}],"version-history":[{"count":8,"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/posts\/2872\/revisions"}],"predecessor-version":[{"id":2961,"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/posts\/2872\/revisions\/2961"}],"wp:attachment":[{"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/media?parent=2872"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/categories?post=2872"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/tags?post=2872"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}