Cách di chuyển / đổi tên tệp bằng tác vụ Ansible trên hệ thống từ xa


202

Làm thế nào có thể di chuyển / đổi tên tệp / thư mục bằng mô-đun Ansible trên hệ thống từ xa? Tôi không muốn sử dụng các tác vụ lệnh / shell và tôi không muốn sao chép tệp từ hệ thống cục bộ sang hệ thống từ xa.


Tại sao bạn không muốn sử dụng lệnh / shell?
Nick Urban

4
Chỉ muốn biết nếu có một cách mà không sử dụng các nhiệm vụ được đề cập. Hình như không có cách nào khác vào lúc này.
Christian Berendt

1
Tại sao bạn muốn di chuyển nó một cách cụ thể thay vì sao chép nó? Điều đó có vẻ như là một hành động một lần, chứ không phải là một loại bước đảm bảo trạng thái bình thường.
Nick Urban

2
Tôi có một tệp cấu hình mẫu được bao gồm trong gói RPM và tôi muốn di chuyển tệp cấu hình mẫu này.
Christian Berendt

1
Hiện tại tôi đang sử dụng một liên kết tượng trưng để tham chiếu tệp. Sử dụng get_url không phải là tùy chọn đối với tôi vì hệ thống không thể truy cập internet.
Christian Berendt

Câu trả lời:


201

Mô-đun tệp không sao chép tệp trên hệ thống từ xa. Tham số src chỉ được sử dụng bởi mô-đun tệp khi tạo liên kết tượng trưng đến tệp.

Nếu bạn muốn di chuyển / đổi tên tập tin hoàn toàn trên một hệ thống từ xa thì cách tốt nhất của bạn là sử dụng mô-đun lệnh để chỉ cần gọi lệnh thích hợp:

- name: Move foo to bar
  command: mv /path/to/foo /path/to/bar

Nếu bạn muốn có được sự ưa thích thì trước tiên bạn có thể sử dụng mô-đun stat để kiểm tra xem foo có thực sự tồn tại không:

- name: stat foo
  stat: path=/path/to/foo
  register: foo_stat

- name: Move foo to bar
  command: mv /path/to/foo /path/to/bar
  when: foo_stat.stat.exists

3
Không sử dụng mô-đun lệnh, về lựa chọn duy nhất khác của bạn là viết mô-đun tùy chỉnh của riêng bạn.
Bruce P

2
Được gắn thẻ là câu trả lời đúng vì đây là cách hiện tại để sao chép các tệp từ xa.
Christian Berendt

11
Liên quan đến việc tìm kiếm trước khi bạn nhảy: có lý do nào để không sử dụng removestùy chọn cho commandmô-đun (tài liệu ở đây ) không? Có vẻ như tùy chọn đó sẽ làm cho Ansible kiểm tra trước.
Jim Witschey 14/2/2015

2
Ansible theo dõi các thay đổi để thông báo cho người xử lý, điều này làm cho giải pháp này không tối ưu.
boh

3
Bạn không phải tự kiểm tra sự tồn tại của tệp nếu bạn sử dụng removes: /path/to/foocreates: /path/to/bar. @Fonant đã đề cập đến điều này như nhận xét về một câu trả lời khác, nhưng vì đây là câu trả lời được chấp nhận, tôi muốn chỉ ra nó một lần nữa.
Michael Trojanek

218

Từ phiên bản 2.0 , trong mô-đun sao chép, bạn có thể sử dụng remote_srctham số.

Nếu Truenó sẽ đi đến máy từ xa / đích cho src.

- name: Copy files from foo to bar
  copy: remote_src=True src=/path/to/foo dest=/path/to/bar

Nếu bạn muốn di chuyển tệp, bạn cần xóa tệp cũ bằng mô-đun tệp

- name: Remove old files foo
  file: path=/path/to/foo state=absent

Từ mô-đun sao chép phiên bản 2.8remote_src hỗ trợ sao chép đệ quy.


29
Nhận xét nhỏ: "Hiện tại remote_src không hỗ trợ sao chép đệ quy." lấy từ tài liệu mô-đun ansible. Vì vậy, nếu bạn muốn sao chép đệ quy, bạn vẫn cần mô-đun shell / lệnh.
klaas

23
Tôi không hiểu Sao chép sau đó xóa không giống như di chuyển. Đối với một, nó không phải là nguyên tử. Đối với người khác, nó chậm hơn, đặc biệt là đối với các tệp lớn. Tôi mới biết về Ansible, nhưng điều này có vẻ thực sự kỳ lạ với tôi.
mlissner

19
@alex những gì tôi đang nói không thể là cách đúng đắn để làm điều này. Tôi đang đi ngược lại với 50 thứ gì đó, nhưng điều này thật điên rồ. Một vấn đề khác: quyền và các thuộc tính khác không được duy trì. Khác: Nếu tập tin bị thay đổi trong quá trình sao chép thì sao ?
mlissner

2
@ Hamish Downer và mlissner. Tôi không nói rằng đó là giải pháp tốt nhất cho mọi nhu cầu của bạn. Ngoài ra tôi đã viết rằng nếu bạn muốn sao chép nhiều tập tin, bạn không nên sử dụng mô-đun sao chép. Đọc câu hỏi "Tôi không muốn sử dụng các tác vụ lệnh / shell".
Alex

7
@Alex đây là câu trả lời được bình chọn cao thứ hai trong một câu hỏi về các tập tin di chuyển tự do. Câu hỏi không phải là về sao chép. Có nhiều vấn đề với việc sao chép thay vì di chuyển do đó câu trả lời này không chính xác. Vì vậy, nó nhận được một downvote. Nghi thức xã giao trên SO là để giải thích downvote. Như đã lưu ý ở nơi khác, lựa chọn tốt nhất cho đến nay làcommand: mv /path/to/foo /path/to/bar creates=/path/to/bar removes=/path/to/foo
Alec Wenzowski

106

Tôi đã tìm thấy tùy chọn tạo trong mô-đun lệnh hữu ích. Còn cái này thì sao:

- name: Move foo to bar
  command: creates="path/to/bar" mv /path/to/foo /path/to/bar

Tôi đã từng thực hiện một cách tiếp cận 2 nhiệm vụ bằng cách sử dụng stat như Bruce P gợi ý. Bây giờ tôi làm điều này như một nhiệm vụ với tạo. Tôi nghĩ rằng điều này là rõ ràng hơn nhiều.


60
Hoặc, thậm chí tốt hơn: command: mv /path/to/foo /path/to/bar creates=/path/to/bar removes=/path/to/foo
Fonant

8

Một tùy chọn khác hoạt động tốt với tôi là sử dụng mô-đun đồng bộ hóa . Sau đó loại bỏ thư mục gốc bằng cách sử dụng mô-đun tập tin.

Đây là một ví dụ từ các tài liệu:

- synchronize:
    src: /first/absolute/path
    dest: /second/absolute/path
    archive: yes
  delegate_to: "{{ inventory_hostname }}"

Điều này không hoạt động cục bộ trong mọi trường hợp vì destđược truy cập thông qua SSH ngay cả khi thư mục nằm trên cùng một máy.
Karl Richter

5

Một cách khác để đạt được điều này là sử dụng filevới state: hard.

Đây là một ví dụ tôi có để làm việc:

- name: Link source file to another destination
  file:
    src: /path/to/source/file
    path: /target/path/of/file
    state: hard

Chỉ được thử nghiệm trên localhost (OSX), nhưng cũng hoạt động trên Linux. Tôi không thể nói cho Windows.

Lưu ý rằng đường dẫn tuyệt đối là cần thiết. Khác nó sẽ không cho phép tôi tạo liên kết. Ngoài ra, bạn không thể vượt qua các hệ thống tập tin, vì vậy làm việc với bất kỳ phương tiện được gắn nào có thể thất bại.

Liên kết cứng rất giống với việc di chuyển, nếu bạn xóa tệp nguồn sau đó:

- name: Remove old file
  file:
    path: /path/to/source/file
    state: absent

Một lợi ích khác là những thay đổi được duy trì khi bạn đang ở giữa một vở kịch. Vì vậy, nếu ai đó thay đổi nguồn, mọi thay đổi sẽ được phản ánh trong tệp đích.

Bạn có thể xác minh số lượng liên kết đến một tập tin thông qua ls -l. Số lượng liên kết cứng được hiển thị bên cạnh chế độ (ví dụ: rwxr-xr-x 2, khi một tệp có 2 liên kết).


2
Thật không may, điều này sẽ không làm việc cho một thư mục, như liên kết cứng không được phép cho thư mục (((
Drew

1
Câu trả lời này đưa ra một giả định về hệ thống đích, cụ thể là cả src và Dest đều nằm trên cùng một phân vùng. Điều này có thể không đúng và do đó câu trả lời này không nên được sử dụng.
mikky

4

Bruce đã không cố gắng thống kê điểm đến để kiểm tra xem có nên di chuyển tệp hay không nếu nó đã ở đó; ông đã chắc chắn rằng tập tin được di chuyển thực sự tồn tại trước khi thử mv.

Nếu sở thích của bạn, như của Tom, là chỉ di chuyển nếu tệp không tồn tại, tôi nghĩ chúng ta vẫn nên tích hợp kiểm tra của Bruce vào hỗn hợp:

- name: stat foo
  stat: path=/path/to/foo
  register: foo_stat

- name: Move foo to bar
  command: creates="path/to/bar" mv /path/to/foo /path/to/bar
  when: foo_stat.stat.exists

3

Đây là cách tôi làm cho nó hoạt động với tôi:

  Tasks:
  - name: checking if the file 1 exists
     stat:      
      path: /path/to/foo abc.xts
     register: stat_result

  - name: moving file 1
    command: mv /path/to/foo abc.xts /tmp
    when: stat_result.stat.exists == True

Playbook ở trên, sẽ kiểm tra xem tập tin abc.xts có tồn tại hay không trước khi di chuyển tập tin vào thư mục tmp.


3
Không cần sử dụng when: stat_result.stat.exists == True. Chỉ cần sử dụng when: stat_result.stat.existslà đủ tốt.
kuttumiah

Tôi thường sử dụng == Truevì tôi luôn làm gì đó khi không tìm thấy tệp hoặc == False.
eduprado

Theo trang tài liệu chính thức của thuộc tính statmô-đun exists trả về một booleangiá trị. Vì vậy, nếu bạn chỉ đặt when: stat_result.stat.existsđiều đó sẽ thỏa mãn điều kiện nếu tệp có mặt giống hệt với when: stat_result.stat.exists == Truenhưng có nhiều văn bản hơn và kiểm tra điều kiện không cần thiết.
kuttumiah

0

Điều này có vẻ như quá mức cần thiết, nhưng nếu bạn muốn tránh sử dụng mô-đun lệnh (mà tôi làm, bởi vì nó sử dụng lệnh không phải là idempotent), bạn có thể sử dụng kết hợp giữa sao chép và không lưu trữ.

  1. Sử dụng tar để lưu trữ (các) tệp bạn sẽ cần. Nếu bạn nghĩ trước điều này thực sự có ý nghĩa. Bạn có thể muốn một loạt các tập tin trong một thư mục nhất định. Tạo thư mục đó với tất cả các tệp và lưu trữ chúng trong một tar.
  2. Sử dụng mô-đun không lưu trữ. Khi bạn làm điều đó, cùng với đích: và remote_src: keyword, bạn có thể đặt bản sao tất cả các tệp của mình vào một thư mục tạm thời để bắt đầu và sau đó giải nén chúng chính xác nơi bạn muốn.

Không có sự bình tĩnh trong việc lưu trữ với tar
truy cập1985

0

Bạn có thể làm điều đó bằng cách -

Sử dụng lệnh Ad Hoc

ansible all -m command -a" mv /path/to/foo /path/to/bar"

Hoặc Bạn nếu bạn muốn làm điều đó bằng cách sử dụng playbook

- name: Move File foo to destination bar
  command: mv /path/to/foo /path/to/bar

0

Tôi biết đó là một chủ đề cũ NĂM , nhưng tôi đã nản lòng và xây dựng một vai trò cho chính mình để thực hiện chính xác điều này cho một danh sách các tệp tùy ý. Mở rộng khi bạn thấy phù hợp:

chính.yml

- name: created destination directory
  file:
    path: /path/to/directory
    state: directory
    mode: '0750'
- include_tasks: move.yml
  loop:
    - file1
    - file2
    - file3

di chuyển.yml

- name: stat the file
  stat:
    path: {{ item }}
  register: my_file

- name: hard link the file into directory
  file:
    src: /original/path/to/{{ item }}
    dest: /path/to/directory/{{ item }}
    state: hard
  when: my_file.stat.exists

- name: Delete the original file
  file:
    path: /original/path/to/{{ item }}
    state: absent
  when: my_file.stat.exists

Lưu ý rằng liên kết cứng tốt hơn là sao chép ở đây, vì nó vốn bảo toàn quyền sở hữu và quyền (ngoài việc không tiêu tốn thêm dung lượng đĩa cho bản sao thứ hai của tệp).


0

Trên Windows: - name: Move old folder to backup win_command: "cmd.exe /c move /Y {{ sourcePath }} {{ destinationFolderPath }}"

Để đổi tên sử dụng đổi tên hoặc ren lệnh thay vì

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.