How Linux Works Chương 13 · User Environments

Chương 13 · Môi trường người dùng Chapter 13 · User Environments

Hệ thống và người dùng phải gặp nhau ở đâu đó — chỗ đó là tệp khởi động Mấy tệp nhỏ quyết định máy chào bạn thế nào The system and the user have to meet somewhere — that somewhere is the startup file

Brian Ward mở chương bằng một lời thú nhận về phạm vi: quyển sách chủ yếu nói về những phần của hệ thống Linux nằm dưới các tiến trình máy chủ và các phiên làm việc tương tác. Nhưng rốt cuộc, hệ thống và người dùng vẫn phải gặp nhau ở đâu đó — và tệp khởi động chính là điểm gặp ấy, vì chúng đặt giá trị mặc định cho shell cùng các chương trình tương tác khác, và quyết định hệ thống cư xử ra sao khi một người dùng đăng nhập.1

Khi bạn mở cửa sổ dòng lệnh, máy không hiện ra một cách ngẫu nhiên đâu. Có vài tệp nhỏ nằm sẵn trong thư mục nhà của bạn, ghi những câu như “tìm lệnh ở đâu”, “dấu nhắc trông thế nào”, “mở tệp văn bản bằng chương trình nào”. Máy đọc mấy tệp đó rồi mới chào bạn. Nhớ nhé: máy chào bạn theo đúng những gì bạn viết sẵn trong tệp khởi động.

Brian Ward opens the chapter with an admission about scope: the book focuses mainly on the parts of the Linux system that normally underlie server processes and interactive user sessions. But eventually the system and the user have to meet somewhere — and startup files are that meeting point, because they set defaults for the shell and other interactive programs, and determine how the system behaves when a user logs in.1

Ward mô tả chính xác cái vòng đời khiến các tệp này trở thành vấn đề: phần lớn người dùng không mấy để tâm tới tệp khởi động của mình, chỉ đụng vào khi muốn thêm một thứ gì đó cho tiện — chẳng hạn một alias. Theo thời gian, các tệp ấy bị chất đống bởi những biến môi trường không cần thiết và những phép kiểm tra thừa, dẫn tới các vấn đề gây khó chịu — hoặc khá nghiêm trọng.1 Đó là lý do một chương chỉ dài mười một trang lại đứng ngang hàng với các chương về nhân và hệ thống tệp: nó nói về thứ duy nhất trong hệ thống mà bạn là tác giả.

Luận đề của chương: tệp khởi động shell nên ít, ngắn, đơn giản và có chú thích đầy đủ; bạn chỉ cần nắm một nhúm thành phần thiết yếu — đường dẫn lệnh, dấu nhắc, alias, mặt nạ quyền — và nắm đúng thứ tự mà shell đọc các tệp, bởi vì chính việc chọn sai tệp mới là phần khó nhất.1

Ý chính: viết ít thôi, viết ngắn thôi, và ghi chú cho rõ. Rồi nhớ xem máy đọc tệp nào trước, tệp nào sau. Nhớ nhé: ít mà đúng chỗ, hơn nhiều mà rối.

The chapter's thesis: shell startup files should be few, short, simple and heavily commented; you only need a handful of essential elements — the command path, the prompt, aliases, the permissions mask — plus a correct grasp of the order in which the shell reads those files, because choosing the right file is the genuinely hard part.1

Cụm khái niệm 01 Concept cluster 01

Tệp dot, hai mục tiêu thiết kế, và khi nào thì nên sửa Tệp chấm là gì, và khi nào nên đụng vào Dot files, two design goals, and when to alter them

Nếu bạn đã dùng máy Linux một thời gian, thư mục nhà của bạn hẳn đã tích tụ một lượng tệp khởi động nhiều đến mức khó hiểu. Ward gọi chúng là dot file, vì chúng gần như luôn bắt đầu bằng một dấu chấm — nhờ đó bị loại khỏi phần hiển thị mặc định của ls và của hầu hết trình quản lý tệp. Nhiều tệp trong số đó được tự động tạo ra lần đầu bạn chạy một chương trình, và bạn sẽ chẳng bao giờ cần sửa chúng; chương này chủ yếu bàn về tệp khởi động shell — nhóm bạn có nhiều khả năng sửa hoặc viết lại từ đầu nhất.1

Trong thư mục nhà của bạn có nhiều tệp tên bắt đầu bằng dấu chấm, ví dụ .bashrc. Vì có dấu chấm nên bình thường bạn không thấy chúng — muốn thấy thì phải bảo ls hiện ra. Phần lớn là do các chương trình tự tạo, bạn cứ để yên. Chương này chỉ nói về vài tệp của shell thôi. Nhớ nhé: tệp bắt đầu bằng dấu chấm là tệp ẩn, và bạn chỉ cần quan tâm mấy tệp của shell.

If you've had your Linux machine for a while, your home directory has probably accumulated a bafflingly large array of startup files. Ward calls them dot files, because they nearly always start with a dot — which excludes them from the default display of ls and of most file managers. Many are created automatically the first time you run a program, and you'll never need to change them; this chapter primarily covers shell startup files, the ones you're most likely to modify or rewrite from scratch.1

Định nghĩa. Tệp khởi động (startup file) là tệp mà shell đọc và thực thi khi nó bắt đầu chạy, trước khi trao dấu nhắc cho bạn. Trong bash, tài liệu chính thức mô tả nhóm này gồm /etc/profile, ~/.bash_profile, ~/.bash_login, ~/.profile và ~/.bashrc; nếu một tệp tồn tại nhưng không đọc được, bash báo lỗi.2

Nói đơn giản. Tệp khởi động là tờ giấy dặn dò bạn để sẵn cho shell: “trước khi nói chuyện với tôi, hãy làm mấy việc này”. Nhớ nhé: shell đọc tờ giấy đó trước, rồi mới chào bạn.

Definition. A startup file is a file the shell reads and executes as it starts, before handing you a prompt. For bash, the reference manual describes this group as /etc/profile, ~/.bash_profile, ~/.bash_login, ~/.profile and ~/.bashrc; if any of these files exists but cannot be read, bash reports an error.2

Simplicity → ít tệp, ngắn, khó hỏng
Readability → chú thích dày đặc
---
mỗi mục thêm vào
  = một thứ nữa có thể hỏng

Ít tệp + ngắn gọn
+ ghi chú rõ ràng
= tệp khởi động tốt

Simplicity → few files, short, hard to break
Readability → extensive comments
---
each item you add
  = one more thing that can break

  1. dot file

    Dot file — tệp cấu hình ẩn trong thư mục nhà Dot file — tệp có dấu chấm ở đầu tên Dot file — the hidden config in your home directory

    Cái tên chỉ mô tả một quy ước đặt tên, không phải một cơ chế của nhân: vì tên bắt đầu bằng dấu chấm, công cụ liệt kê tệp bỏ qua chúng trong danh sách mặc định.1 Bản thân ls chỉ hiện chúng khi bạn yêu cầu tường minh bằng -a (hiện tất cả) hoặc -A (tất cả, trừ . và ..).3

    Dấu chấm ở đầu tên chỉ là một quy ước để giấu bớt cho đỡ rối mắt, chứ không phải khoá bảo mật gì cả. Gõ ls -a là thấy hết. Nhớ nhé: ẩn không có nghĩa là bí mật.

    The name describes a naming convention, not a kernel mechanism: because the name begins with a dot, listing tools omit these files from the default display.1 ls itself shows them only when you ask explicitly, with -a (show all) or -A (all except . and ..).3

    Bạn gặp nó ở đâuWhere you meet it Lần đầu bạn chạy một chương trình mới và nó lặng lẽ sinh ra một thư mục cấu hình trong $HOME mà bạn không hề thấy trong ls. Mỗi lần bạn mở một phần mềm mới và nó tự nhớ thiết lập của bạn cho lần sau. The first time you run a new program and it quietly creates a configuration directory in $HOME that never shows up in ls.

    Lời dặn của tác giả

    Ward nói rõ rằng phần lớn các dot file này bạn sẽ không bao giờ cần sửa; chỉ có nhóm tệp khởi động shell mới đáng để bạn bỏ công.1 Đây là một phép chọn lọc chủ động: biết cái gì không cần động tới cũng quan trọng ngang biết cái gì cần.

    Cái giá của sự tích tụ

    Theo thời gian, các tệp trở nên bừa bộn với những biến môi trường không cần thiết và những phép kiểm tra thừa, dẫn tới các vấn đề gây khó chịu hoặc khá nghiêm trọng.1 Cái đắt không phải một dòng sai, mà là một trăm dòng không ai còn nhớ vì sao có ở đó.

  2. simplicity & readability

    Đơn giản và dễ đọc — hai mục tiêu duy nhất Viết ngắn và ghi chú rõ Simplicity and readability — the only two goals

    Khi tạo tệp khởi động cho người khác, Ward yêu cầu giữ hai mục tiêu thiết yếu trong đầu. Simplicity: giữ số tệp ít, và giữ mỗi tệp ngắn và đơn giản nhất có thể, sao cho chúng dễ sửa mà khó hỏng — vì “mỗi mục trong một tệp khởi động chỉ là thêm một thứ nữa có thể hỏng”. Readability: dùng chú thích thật rộng rãi, để người dùng hình dung được mỗi phần của tệp làm gì.1

    Chỉ cần nhớ hai điều: viết ít thôi, và viết chú thích cho rõ. Càng thêm nhiều dòng, càng nhiều chỗ có thể hỏng. Nhớ nhé: mỗi dòng bạn thêm vào là một dòng có thể làm bạn khổ sau này.

    When creating startup files for other users, Ward asks you to keep two essential goals in mind. Simplicity: keep the number of startup files small, and keep each file as short and simple as possible, so they're easy to modify but hard to break — because "each item in a startup file is just one more thing that can break." Readability: use extensive comments so users get a good picture of what each part of a file does.1

    Bạn gặp nó ở đâuWhere you meet it Khi bạn chép tệp khởi động của mình sang một máy mới và mất nửa buổi để hiểu dòng thứ ba mình viết năm ngoái để làm gì. Khi bạn mở lại tệp cũ của chính mình và không còn nhớ nổi mình đã viết gì. When you copy your own startup files to a new machine and lose half a morning working out what line three was for.

    Vì sao quy mô thay đổi mọi thứ

    Ward đặt bài toán rất cụ thể: nếu bạn là người dùng duy nhất trên máy thì chẳng có gì phải lo, vì lỗi chỉ ảnh hưởng tới bạn và dễ sửa. Nhưng nếu bạn đang tạo tệp khởi động làm mặc định cho mọi người dùng mới trên một máy hay một mạng, quá trình này trở nên nghiêm trọng hơn hẳn — “nếu bạn phạm một lỗi trong tệp khởi động rồi phát cho 10 người dùng, bạn có thể sẽ phải sửa lỗi đó 10 lần”.1

    Rủi ro lan truyền

    Ông thêm một trường hợp dễ bị bỏ sót: ngay cả khi bạn không cố ý phân phát, vẫn có khả năng ai đó chép tệp của bạn để dùng trên một máy khác.1 Tệp khởi động là thứ lan truyền bằng sao chép, không bằng cài đặt — nên nó không có cơ chế cập nhật nào cả.

  3. when to alter

    Khi nào thì nên sửa — ba lý do chính đáng Ba lúc nên sửa, còn lại thì thôi When to alter — three good reasons

    Trước khi thay đổi một tệp khởi động, Ward bảo hãy tự hỏi liệu bạn có thật sự nên làm việc đó không. Ông liệt kê ba lý do chính đáng: bạn muốn đổi dấu nhắc mặc định; bạn cần đáp ứng một phần mềm cài đặt cục bộ có tính then chốt (dù vậy, hãy cân nhắc dùng wrapper script trước đã); hoặc các tệp khởi động hiện có của bạn đã hỏng.1

    Chỉ sửa khi: bạn muốn đổi dòng chữ dấu nhắc, bạn cần chạy một phần mềm riêng, hoặc tệp cũ đang hỏng. Ngoài ba lý do đó thì cứ để yên. Nhớ nhé: không hỏng thì đừng sửa.

    Before changing a startup file, Ward asks you to question whether you really should. He lists three good reasons: you want to change the default prompt; you need to accommodate some critical locally installed software (though consider a wrapper script first); or your existing startup files are broken.1

    Bạn gặp nó ở đâuWhere you meet it Khi một trình cài đặt hỏi xin “thêm một dòng vào .bashrc của bạn” — đó đúng là lúc nên hỏi lại: có cách nào khác không? Khi một phần mềm xin tự thêm dòng vào tệp của bạn. When an installer asks to "add one line to your .bashrc" — precisely the moment to ask whether there is another way.

    Cảnh báo về tương tác

    Ward dặn: nếu mọi thứ trong bản phân phối Linux của bạn đang chạy tốt, hãy cẩn thận — đôi khi các tệp khởi động mặc định tương tác với những tệp khác trong /etc.1 Nói cách khác, tệp trong thư mục nhà của bạn không sống một mình; nó là một mắt trong chuỗi mà quản trị viên bản phân phối đã dựng sẵn.

    Wrapper script: lựa chọn thay thế

    “Hãy cân nhắc dùng wrapper script trước” không phải một lời khuyên vu vơ. Ward dùng lại đúng kỹ thuật ấy ở Chương 15 cho trường hợp LD_LIBRARY_PATH: thay vì đặt biến trong tệp khởi động — ảnh hưởng tới mọi chương trình — bạn viết một script ngắn đặt biến rồi exec chương trình cần chạy, giới hạn tác động vào đúng một chỗ.4

Cụm khái niệm 02 Concept cluster 02

Năm thành phần: đường dẫn lệnh, đường dẫn man, dấu nhắc, alias, mặt nạ quyền Trong tệp khởi động nên có những gì Five elements: command path, manual path, prompt, aliases, permissions mask

Ward đặt câu hỏi mở đầu rất thẳng: cái gì nên nằm trong một tệp khởi động shell? Vài thứ có vẻ hiển nhiên — đường dẫn lệnh và một thiết lập dấu nhắc. Nhưng chính xác thì trong đường dẫn nên có gì, một dấu nhắc hợp lý trông ra sao, và bao nhiêu là quá nhiều để nhét vào một tệp khởi động?1 Phần này đi qua đúng năm thứ thiết yếu ông liệt kê.

Trong tệp khởi động chỉ cần năm thứ: chỗ tìm lệnh, chỗ tìm trang hướng dẫn, dòng dấu nhắc, mấy lối viết tắt, và quyền mặc định cho tệp mới. Nhớ nhé: năm thứ thôi, đừng thêm.

Ward's opening question is blunt: what goes into a shell startup file? Some things seem obvious — the command path and a prompt setting. But what exactly should be in the path, what does a reasonable prompt look like, and how much is too much to put in a startup file?1 This section walks the five essentials he lists.

Định nghĩa. PATH là chuỗi các tiền tố thư mục mà shell và nhiều chương trình khác dùng khi tìm một tệp thực thi được chỉ định bằng tên đơn giản (tên không chứa dấu gạch chéo). Các tiền tố ngăn cách bằng dấu hai chấm, và danh sách được duyệt từ đầu đến cuối.5

Nói đơn giản. PATH là danh sách các ngăn tủ. Bạn gõ tên một lệnh, máy mở lần lượt từng ngăn từ trái sang phải, thấy ở ngăn nào trước thì dùng cái đó. Nhớ nhé: ngăn đứng trước thì thắng.

Definition. PATH is the sequence of directory prefixes the shell and many other programs use when searching for an executable named by a simple filename (one containing no slashes). Prefixes are separated by colons, and the list is searched from beginning to end.5

# tối thiểu, đúng thứ tự
/usr/local/bin
/usr/bin
/bin

# tuỳ chọn, thêm vào đầu
$HOME/bin

/usr/local/bin
/usr/bin
/bin
(+ $HOME/bin nếu muốn)

# minimum, in this order
/usr/local/bin
/usr/bin
/bin

# optional, at the front
$HOME/bin

  1. the command path

    Command path — phần quan trọng nhất của tệp Đường dẫn lệnh — chỗ máy đi tìm lệnh The command path — the most important part of the file

    Ward gọi đường dẫn lệnh là phần quan trọng nhất của bất kỳ tệp khởi động shell nào. Nó phải bao phủ các thư mục chứa mọi ứng dụng mà một người dùng thông thường quan tâm, và tối thiểu phải chứa ba thành phần này, theo thứ tự: /usr/local/bin, /usr/bin, /bin. Thứ tự ấy bảo đảm rằng bạn có thể ghi đè các chương trình mặc định chuẩn bằng biến thể riêng của site đặt trong /usr/local.1

    Đây là phần quan trọng nhất. Ba ngăn tủ theo đúng thứ tự: /usr/local/bin trước, rồi /usr/bin, rồi /bin. Đặt ngăn “của riêng máy này” lên trước để nó thắng ngăn chung. Nhớ nhé: cái riêng đứng trước cái chung.

    Ward calls the command path the most important part of any shell startup file. It should cover the directories containing every application of interest to a regular user, and at minimum must contain these three components, in order: /usr/local/bin, /usr/bin, /bin. That order ensures you can override standard default programs with site-specific variants located in /usr/local.1

    Bạn gặp nó ở đâuWhere you meet it Khi hai phiên bản của cùng một công cụ cùng tồn tại trên máy và bạn cần biết phiên bản nào sẽ chạy — câu trả lời nằm ở thứ tự trong PATH. Khi máy chạy nhầm phiên bản cũ của một lệnh. When two versions of the same tool coexist on a machine and you need to know which one runs — the answer is the order inside PATH.

    Vì sao /usr/local đứng trước

    Chuẩn FHS dành riêng cây /usr/local cho quản trị viên khi cài phần mềm cục bộ, và nó phải an toàn trước việc bị ghi đè khi phần mềm hệ thống được cập nhật; phần mềm cài cục bộ phải được đặt trong /usr/local thay vì /usr, trừ khi nó nhằm thay thế hoặc nâng cấp phần mềm trong /usr.6 Quy tắc thứ tự của Ward chỉ là hệ quả thực hành của ranh giới ấy.

    Đừng nối dài PATH theo từng phần mềm

    Ward dặn đừng đổi đường dẫn mặc định trong môi trường người dùng để chiều theo mỗi thư mục cài đặt phần mềm mới; cách rẻ tiền để dung nạp các thư mục cài đặt riêng là dùng liên kết tượng trưng trong /usr/local/bin.1 Ông cũng lưu ý rằng nếu một chương trình dùng chung nào đó không truy cập được qua các thư mục nói trên, thì hệ thống của bạn có lẽ đang vượt khỏi tầm kiểm soát.1

    Thư mục riêng và các thư mục sbin

    Nhiều người tạo một thư mục bin của riêng mình để chứa script và chương trình, nên bạn có thể muốn thêm $HOME/bin vào đầu đường dẫn; Ward ghi chú rằng một quy ước mới hơn là đặt các tệp nhị phân trong $HOME/.local/bin.1 Quy ước ấy cũng được đặc tả phân cấp tệp của UAPI/systemd liệt kê như vị trí chuẩn cho tệp thực thi thuộc về một người dùng.7 Nếu bạn quan tâm tới các tiện ích hệ thống như sysctl, fdisk, lsmod, hãy thêm /usr/local/sbin, /usr/sbin, /sbin.1

    Dấu chấm trong PATH: đừng

    Ward dành hẳn một khung cho một thành phần nhỏ nhưng gây tranh cãi: dấu chấm. Đặt . vào đường dẫn cho phép bạn chạy chương trình trong thư mục hiện tại mà không cần ./ ở đầu tên — nhưng đó là một ý tồi vì hai lý do. Một, nó là vấn đề an ninh: bạn không bao giờ nên đặt dấu chấm ở đầu đường dẫn, vì kẻ tấn công có thể đặt một con ngựa thành Troy tên ls trong một kho lưu trữ phát tán trên internet; và ngay cả khi dấu chấm nằm ở cuối, bạn vẫn dễ tổn thương trước kẻ đoán trước các lỗi gõ nhầm như sl hay ks. Hai, nó thiếu nhất quán và dễ gây lẫn lộn: một dấu chấm trong đường dẫn có nghĩa là hành vi của một lệnh sẽ thay đổi tuỳ theo thư mục hiện tại.1

  2. the manual page path

    MANPATH — thành phần bạn nên không đặt Đường dẫn trang hướng dẫn — cứ để yên MANPATH — the element you should not set

    Đây là mục ngắn nhất trong chương, và nội dung của nó là một lời từ chối: đường dẫn trang hướng dẫn theo truyền thống được quy định bởi biến môi trường MANPATH, nhưng bạn không nên đặt nó, vì làm vậy sẽ ghi đè các mặc định hệ thống trong /etc/manpath.config.1

    Có một biến tên MANPATH chỉ chỗ chứa trang hướng dẫn. Đừng đặt nó. Hệ thống tự biết rồi. Nhớ nhé: biết một thứ không nên đụng vào cũng là kiến thức.

    This is the shortest item in the chapter, and its content is a refusal: the traditional manual page path was determined by the MANPATH environment variable, but you shouldn't set it, because doing so overrides the system defaults in /etc/manpath.config.1

    Bạn gặp nó ở đâuWhere you meet it Khi một trang man đáng lẽ phải tồn tại bỗng “không tìm thấy” — thủ phạm rất hay là một MANPATH do ai đó đặt cứng nhiều năm trước. Khi gõ man một lệnh mà máy bảo không có trang hướng dẫn. When a man page that ought to exist comes back "not found" — the culprit is very often a hard-coded MANPATH someone set years ago.

    Cơ chế tự suy ra

    Lý do lời khuyên này đứng vững: theo mặc định, man-db tự khảo sát $PATH của người dùng, và với mỗi thành phần đường dẫn nó thêm một thành phần manpath tương ứng vào đường dẫn tìm kiếm — nếu tệp cấu hình không có dòng MANPATH_MAP cho thành phần đó, nó thêm các thư mục path_element/../man, path_element/man, path_element/../share/man và path_element/share/man nào thật sự tồn tại.8

    Đặt rồi thì hệ thống nhường

    Trang hướng dẫn về định dạng tệp cấu hình nói thẳng: nếu biến môi trường $MANPATH đã được đặt, thông tin trong tệp cấu hình sẽ không ghi đè lên nó.8 Nghĩa là một dòng bạn viết vội trong .bashrc sẽ âm thầm vô hiệu hoá toàn bộ cấu hình của bản phân phối — đúng thứ Ward muốn bạn tránh.

  3. the prompt

    Dấu nhắc — ngắn, và tránh ký tự nguy hiểm Dấu nhắc — dòng chữ trước con trỏ The prompt — short, and free of dangerous characters

    Ward quan sát rằng người dùng có kinh nghiệm thường tránh các dấu nhắc dài, phức tạp và vô dụng, trong khi nhiều quản trị viên và bản phân phối lại lôi mọi thứ vào dấu nhắc mặc định — ngay cả nhiều dấu nhắc mặc định của shell cũng bừa bộn hoặc gần như vô ích; ví dụ dấu nhắc bash mặc định chứa tên shell và số hiệu phiên bản. Lựa chọn của bạn nên phản ánh nhu cầu của người dùng: hãy đặt thư mục làm việc hiện tại, tên máy và tên người dùng vào dấu nhắc nếu nó thật sự giúp ích.1

    Dấu nhắc là dòng chữ máy hiện ra trước chỗ bạn gõ. Đừng nhét quá nhiều thứ vào đó. Chỉ để những gì bạn thật sự cần nhìn. Nhớ nhé: dấu nhắc ngắn thì nhìn lệnh của mình mới rõ.

    Ward observes that experienced users tend to avoid long, complicated, useless prompts, while many administrators and distributions drag everything into the default — even many shell default prompts are cluttered or mostly useless; the default bash prompt, for example, contains the shell name and version number. Your choice should reflect your users' needs: put the current working directory, hostname and username in the prompt if it really helps.1

    Bạn gặp nó ở đâuWhere you meet it Khi bạn chụp màn hình terminal để nhờ người khác xem và nửa bề ngang đã bị dấu nhắc chiếm mất. Khi dòng dấu nhắc dài đến mức lệnh của bạn bị đẩy xuống dòng. When you screenshot a terminal to ask for help and half the width is already taken by the prompt.

    Ký tự phải tránh

    Trên hết, Ward dặn tránh những ký tự có ý nghĩa đặc biệt với shell, cụ thể là: { } = & < >. Ông ghi chú riêng ký tự >: hãy đặc biệt cẩn thận với nó, vì nó có thể khiến những tệp rỗng xuất hiện thất thường trong thư mục hiện tại nếu bạn vô tình sao chép rồi dán một đoạn cửa sổ shell — bởi > chuyển hướng đầu ra vào một tệp.1

    Thiết lập tối thiểu

    Thiết lập đơn giản mà ông đưa ra cho bash kết thúc bằng ký tự $ theo thông lệ (dấu nhắc csh truyền thống kết thúc bằng %): PS1='\u\$ '. Trong đó \u là một biểu thức mà shell ước lượng thành tên người dùng hiện tại — xem mục PROMPTING của trang hướng dẫn bash(1).1

    Bốn biểu thức thông dụng khác

    Ward liệt kê: \h tên máy (dạng ngắn, không có tên miền); \! số hiệu lịch sử; \w thư mục hiện tại — vì nó có thể dài, bạn có thể giới hạn hiển thị chỉ còn thành phần cuối bằng \W; và \$ cho ra $ nếu đang chạy dưới tài khoản người dùng, # nếu là root.1 Trang bash(1) xác nhận từng mục: \h là tên máy tính tới dấu chấm đầu tiên, \w là giá trị $PWD với $HOME viết tắt thành dấu ngã, \W là thành phần cuối của $PWD, \! là số hiệu lịch sử của lệnh này, và \$ cho # nếu UID hiệu dụng bằng 0, ngược lại cho $.9

  4. aliases

    Alias — tiện, nhưng hãy tránh khi có thể Alias — lối viết tắt cho lệnh Aliases — handy, but avoid them where you can

    Ward xếp alias vào “những điểm gai góc hơn” của môi trường người dùng đương đại: đó là một tính năng của shell thay thế một chuỗi này bằng một chuỗi khác trước khi thực thi lệnh. Alias có thể là lối tắt hiệu quả giúp đỡ phải gõ, nhưng chúng có vài nhược điểm — thao tác với tham số có thể rắc rối; chúng gây lẫn lộn, vì lệnh dựng sẵn which của shell có thể cho bạn biết một thứ có phải alias hay không nhưng không nói nó được định nghĩa ở đâu; và chúng bị xem thường trong subshell và shell không tương tác, vì không được truyền xuống shell con.1

    Alias là lối viết tắt: bạn đặt một tên ngắn cho một lệnh dài. Tiện thật, nhưng dễ làm bạn quên mất lệnh thật trông thế nào, và nó không theo bạn vào các shell khác. Nhớ nhé: viết tắt cho mình thì được, đừng ép người khác dùng.

    Ward files aliases under the "stickier points" of contemporary user environments: an alias is a shell feature that substitutes one string for another before executing a command. Aliases can be efficient shortcuts that save typing, but they have several drawbacks — manipulating arguments can be tricky; they're confusing, since a shell's built-in which can tell you whether something is an alias but not where it was defined; and they're frowned upon in subshells and noninteractive shells, since they aren't passed on to child shells.1

    Bạn gặp nó ở đâuWhere you meet it Khi một script bạn viết chạy khác hẳn lúc bạn gõ tay cùng lệnh đó — vì script là shell không tương tác, và alias không có ở đó. Khi lệnh chạy trong script không giống lúc bạn tự gõ. When a script you wrote behaves differently from the same command typed by hand — because a script is a noninteractive shell, and your alias isn't there.

    Sai lầm kinh điển

    Ward chỉ đích danh: một sai lầm kinh điển khi định nghĩa alias là thêm tham số phụ vào một lệnh sẵn có — chẳng hạn đặt alias ls thành ls -F. Tốt nhất thì nó khiến bạn khó gỡ bỏ tham số -F khi không muốn dùng; tệ nhất thì nó gây hậu quả nghiêm trọng cho người dùng không hiểu rằng họ không đang dùng tham số mặc định.1

    Hàm shell thay vì alias

    Kết luận của ông: với những nhược điểm ấy, bạn nên tránh alias bất cứ khi nào có thể — viết một hàm shell hay hẳn một script mới còn dễ hơn; máy tính khởi động và thực thi shell nhanh đến mức khác biệt giữa một alias và một lệnh hoàn toàn mới là không đáng kể.1 Trang bash(1) nói cùng một điều theo lối kỹ thuật: không có cơ chế dùng tham số trong văn bản thay thế của alias — nếu cần tham số, hãy dùng hàm shell; và “với hầu hết mọi mục đích, hàm shell được ưa chuộng hơn alias”.9

    Chỗ alias vẫn hữu dụng

    Ward không cấm tuyệt đối: alias vẫn tiện khi bạn muốn thay đổi một phần môi trường của shell. Bạn không thể đổi một biến môi trường bằng một script, vì script chạy như subshell — nhưng bạn có thể định nghĩa hàm shell để làm việc đó.1

  5. the permissions mask

    umask — 022 hay 077, và vì sao umask — ai được xem tệp bạn tạo umask — 022 or 077, and why

    Như đã mô tả ở Chương 2, tiện ích dựng sẵn umask (mặt nạ quyền) của shell đặt quyền mặc định của bạn. Ward khuyên đưa lệnh umask vào một trong các tệp khởi động để chắc chắn rằng mọi chương trình bạn chạy đều tạo tệp với quyền bạn mong muốn, và ông đưa ra hai lựa chọn hợp lý: 077 — mặt nạ hạn chế nhất, không cho người dùng nào khác truy cập tệp và thư mục mới; và 022 — cho người khác quyền đọc với tệp và thư mục mới.1

    umask quyết định người khác có xem được tệp bạn vừa tạo hay không. 022 nghĩa là người khác đọc được; 077 nghĩa là chỉ mình bạn. Nhớ nhé: 022 là mở cho xem, 077 là giữ riêng.

    As described in Chapter 2, a shell's built-in umask (permissions mask) facility sets your default permissions. Ward recommends including the umask command in one of your startup files to be certain that any program you run creates files with the permissions you want, and offers two reasonable choices: 077 — the most restrictive mask, giving no other user access to new files and directories; and 022 — giving other users read access to new files and directories.1

    Bạn gặp nó ở đâuWhere you meet it Khi một tiến trình nền chạy dưới một tài khoản khác báo “permission denied” với đúng tệp bạn vừa tạo. Khi bạn gửi tệp cho bạn bè mà họ mở không được. When a background process running as another account reports "permission denied" on precisely the file you just created.

    Đánh đổi giữa hai lựa chọn

    Ward cân nhắc cả hai chiều. 077 thường thích hợp trên hệ thống nhiều người dùng khi bạn không muốn ai xem tệp của mình; nhưng khi đặt làm mặc định, nó đôi khi gây rắc rối cho người dùng muốn chia sẻ tệp mà không hiểu cách đặt quyền cho đúng — người thiếu kinh nghiệm có xu hướng đặt tệp thành chế độ ai cũng ghi được. Ngược lại, 022 là lựa chọn tốt trên hệ thống một người dùng, vì nhiều daemon chạy dưới dạng “người dùng giả” sẽ không thấy được tệp và thư mục tạo ra với mặt nạ 077 chặt hơn.1

    Cơ chế: mặt nạ là phép trừ

    Trang umask(2) mô tả chính xác cơ chế: lời gọi đặt mặt nạ tạo chế độ tệp của tiến trình thành mask & 0777, và mặt nạ được dùng bởi open(2), mkdir(2) cùng các lời gọi tạo tệp khác — cụ thể, các quyền có trong umask bị tắt khỏi đối số chế độ. Giá trị mặc định điển hình của umask tiến trình đúng là octal 022.10

    Có chương trình ghi đè umask

    Ward ghi chú: một số ứng dụng — đặc biệt là các chương trình thư điện tử — ghi đè umask, đổi nó thành 077, vì chúng cho rằng tệp của chúng không phải việc của ai ngoài chủ sở hữu.1 Nói cách khác, dòng umask trong tệp khởi động của bạn là một mặc định, không phải một chính sách bắt buộc.

Cụm khái niệm 03 Concept cluster 03

Thứ tự đọc tệp: shell đăng nhập, shell không đăng nhập, và tcsh Máy đọc tệp nào, theo thứ tự nào Startup file order: login shells, non-login shells, and tcsh

Trong bash, bạn có thể chọn giữa các tên tệp khởi động .bash_profile, .profile, .bash_login và .bashrc. Cái nào phù hợp cho đường dẫn lệnh, đường dẫn man, dấu nhắc, alias và mặt nạ quyền của bạn? Câu trả lời của Ward: bạn nên có một tệp .bashrc kèm theo một liên kết tượng trưng .bash_profile trỏ tới .bashrc — bởi có vài kiểu thể hiện shell bash khác nhau.1

Bash có tới bốn tên tệp khởi động khác nhau, nghe rối lắm. Mẹo đơn giản: viết mọi thứ vào .bashrc, rồi làm một lối tắt tên .bash_profile trỏ về nó. Thế là dù máy mở kiểu nào cũng đọc đúng một tệp. Nhớ nhé: một tệp thật, một lối tắt, hết rối.

In bash you can choose among the startup filenames .bash_profile, .profile, .bash_login and .bashrc. Which is right for your command path, manual path, prompt, aliases and permissions mask? Ward's answer: you should have a .bashrc accompanied by a .bash_profile symbolic link pointing at .bashrc — because there are a few different kinds of bash shell instance.1

Định nghĩa. Hai kiểu thể hiện shell chính là tương tác và không tương tác, nhưng ta chỉ quan tâm shell tương tác, vì shell không tương tác (như loại chạy script) thường không đọc tệp khởi động nào. Shell tương tác là loại bạn dùng để chạy lệnh từ một terminal, và chúng lại được phân thành đăng nhập (login) và không đăng nhập (non-login).1

Nói đơn giản. Có hai loại cửa sổ dòng lệnh: loại “vừa mới đăng nhập vào máy”, và loại “mở thêm sau khi đã vào rồi”. Hai loại đọc hai bộ tệp khác nhau. Nhớ nhé: cửa đầu tiên và cửa mở thêm không giống nhau.

Definition. The two main shell instance types are interactive and noninteractive, but only interactive shells matter here, because noninteractive shells (such as those running shell scripts) usually don't read any startup files. Interactive shells are the ones you use to run commands from a terminal, and they are further classified as login or non-login.1

login shell:
  /etc/profile
  → .bash_profile
  → .bash_login
  → .profile
    (chỉ tệp ĐẦU TIÊN thấy)

non-login shell:
  /etc/bash.bashrc
  → .bashrc

Cửa đầu tiên:
  .bash_profile
  (hoặc .bash_login,
   hoặc .profile)

Cửa mở thêm:
  .bashrc

login shell:
  /etc/profile
  → .bash_profile
  → .bash_login
  → .profile
    (ONLY the first one seen)

non-login shell:
  /etc/bash.bashrc
  → .bashrc

  1. login shell

    Login shell — shell khởi đầu, và chuỗi bốn tệp Shell đăng nhập — cửa đầu tiên Login shell — the initial shell, and its chain of four files

    Theo truyền thống, shell đăng nhập là thứ bạn nhận được khi lần đầu đăng nhập vào hệ thống qua terminal bằng một chương trình như /bin/login; đăng nhập từ xa bằng SSH cũng cho bạn một shell đăng nhập. Ý tưởng cơ bản: shell đăng nhập là shell khởi đầu. Bạn có thể biết một shell có phải shell đăng nhập không bằng cách chạy echo $0 — nếu ký tự đầu tiên là một dấu gạch nối, đó là shell đăng nhập.1

    Khi bạn vừa đăng nhập vào máy, cửa sổ đầu tiên mở ra là “shell đăng nhập”. Muốn kiểm tra thì gõ echo $0: nếu thấy có dấu gạch nối ở đầu thì đúng rồi. Nhớ nhé: có dấu gạch nối ở đầu nghĩa là shell đăng nhập.

    Traditionally, a login shell is what you get when you first log in to a system with a terminal, via a program such as /bin/login; logging in remotely with SSH also gives you a login shell. The basic idea is that a login shell is an initial shell. You can tell whether a shell is a login shell by running echo $0 — if the first character is a -, it's a login shell.1

    Bạn gặp nó ở đâuWhere you meet it Mỗi phiên ssh vào một máy chủ; và mỗi lần bạn đăng nhập trên console thật của máy. Mỗi lần bạn ssh vào một máy khác. Every ssh session into a server; and every login on the machine's real console.

    Thứ tự chính xác

    Ward viết: khi bash chạy như một shell đăng nhập, nó chạy /etc/profile. Sau đó nó tìm các tệp .bash_profile, .bash_login và .profile của người dùng, và chỉ chạy tệp đầu tiên nó thấy.1 Tài liệu tham chiếu chính thức của bash nói cùng một trình tự, với một chi tiết bổ sung đáng nhớ: nó đọc và thực thi lệnh từ tệp đầu tiên tồn tại và đọc được.2

    Định nghĩa chuẩn của “login”

    Trang bash(1) định nghĩa hình thức: shell đăng nhập là shell có ký tự đầu tiên của đối số số không là một dấu gạch nối, hoặc được khởi động với tuỳ chọn --login.9 Đó chính là lý do phép thử echo $0 của Ward hoạt động — nó đang đọc trực tiếp đối số số không ấy.

    Ép một shell không tương tác thành login

    Ward lưu ý một khả năng nghe lạ tai: có thể chạy một shell không tương tác như một shell đăng nhập để buộc nó chạy các tệp khởi động — khởi động shell với tuỳ chọn -l hoặc --login.1 Tài liệu bash xác nhận: một shell không tương tác với --login vẫn đọc /etc/profile rồi tệp profile đầu tiên của người dùng.2

    Còn lúc thoát?

    Chương 13 không bàn tới tệp thoát, nhưng chuỗi ấy khép lại đối xứng: theo tài liệu bash, khi một shell đăng nhập tương tác thoát ra, bash đọc và thực thi lệnh từ ~/.bash_logout nếu tệp đó tồn tại.2

  2. non-login shell

    Non-login shell — mọi cửa sổ terminal bạn mở thêm Shell không đăng nhập — cửa mở thêm Non-login shell — every terminal window you open afterwards

    Shell không đăng nhập là một shell bổ sung mà bạn chạy sau khi đã đăng nhập — đơn giản là bất kỳ shell tương tác nào không phải shell đăng nhập. Các chương trình terminal của hệ thống cửa sổ (xterm, GNOME Terminal, v.v.) khởi động shell không đăng nhập, trừ khi bạn yêu cầu tường minh một shell đăng nhập. Khi khởi động ở dạng này, Ward viết, bash chạy /etc/bash.bashrc rồi chạy .bashrc của người dùng.1

    Khi bạn đã vào máy rồi và mở thêm một cửa sổ dòng lệnh nữa, cửa sổ đó là “không đăng nhập”. Nó chỉ đọc .bashrc thôi. Nhớ nhé: cửa sổ mở thêm chỉ đọc .bashrc.

    A non-login shell is an additional shell you run after logging in — simply any interactive shell that isn't a login shell. Windowing-system terminal programs (xterm, GNOME Terminal and so on) start non-login shells unless you specifically ask for a login shell. On starting up this way, Ward writes, bash runs /etc/bash.bashrc and then the user's .bashrc.1

    Bạn gặp nó ở đâuWhere you meet it Mỗi tab mới trong ứng dụng terminal trên máy để bàn của bạn — đó là lý do một thay đổi trong .bash_profile có thể “không có tác dụng” cho tới khi bạn đăng xuất. Mỗi tab mới bạn mở trong cửa sổ dòng lệnh. Every new tab in your desktop terminal app — which is why a change in .bash_profile can seem to "do nothing" until you log out.

    Một khác biệt giữa các nguồn — và nên tin ai

    Về shell không đăng nhập, bản văn của Ward nêu hai tệp: /etc/bash.bashrc rồi .bashrc.1 Tài liệu tham chiếu bash thượng nguồn của GNU chỉ nêu một: khi bash chạy như shell tương tác không phải shell đăng nhập, nó đọc và thực thi lệnh từ ~/.bashrc, nếu tệp đó tồn tại.2 Không bên nào sai: /etc/bash.bashrc là một tệp khởi động toàn hệ thống do các bản phân phối (Debian, Ubuntu và họ hàng) thêm vào qua bản vá, và trang bash(1) của Debian ghi rõ điều đó — “bash đọc và thực thi lệnh từ /etc/bash.bashrc và ~/.bashrc, nếu các tệp này tồn tại”.11 Bài học thực hành: phần của bạn luôn là ~/.bashrc; tệp trong /etc có hay không là tuỳ bản phân phối.

    Vì sao lại có hai loại shell

    Ward giải thích bằng lịch sử: ngày trước, người dùng đăng nhập qua terminal truyền thống bằng một shell đăng nhập, rồi khởi động các subshell không đăng nhập bằng hệ thống cửa sổ hoặc chương trình screen. Với các subshell ấy, việc lặp lại thiết lập môi trường và chạy lại một loạt chương trình đã chạy rồi bị xem là lãng phí. Với shell đăng nhập, bạn có thể chạy các lệnh khởi động “nặng đô” trong một tệp như .bash_profile, chỉ để lại alias và những thứ “nhẹ” khác cho .bashrc.1

  3. display manager

    Vì sao mô hình cũ vỡ trên máy để bàn hiện đại Vì sao bây giờ hơi rối Why the old model breaks on a modern desktop

    Ngày nay, Ward viết, phần lớn người dùng máy để bàn đăng nhập qua một trình quản lý hiển thị đồ hoạ. Hầu hết các trình này khởi động bằng một shell đăng nhập không tương tác để bảo toàn mô hình đăng nhập/không đăng nhập. Khi chúng không làm vậy, bạn buộc phải thiết lập toàn bộ môi trường của mình — đường dẫn, đường dẫn man, v.v. — trong .bashrc, nếu không bạn sẽ chẳng bao giờ thấy môi trường của mình trong các shell cửa sổ terminal.1

    Máy để bàn bây giờ cho bạn đăng nhập bằng màn hình đồ hoạ, nên cái mô hình cũ không còn gọn nữa. Cách an toàn: viết mọi thứ vào .bashrc, rồi cho .bash_profile gọi nó. Nhớ nhé: một chỗ viết, hai đường vào.

    Nowadays, Ward writes, most desktop users log in through a graphical display manager. Most of these start with one noninteractive login shell in order to preserve the login versus non-login model. When they do not, you have to set up your entire environment — path, manual path and so on — in your .bashrc, or you'll never see any of your environment in your terminal-window shells.1

    Bạn gặp nó ở đâuWhere you meet it Khi một biến bạn đặt chạy tốt trong terminal nhưng ứng dụng khởi động từ menu đồ hoạ lại không thấy nó. Khi thiết lập chạy được trong terminal nhưng không chạy trong ứng dụng đồ hoạ. When a variable you set works in the terminal but an app launched from the graphical menu can't see it.

    Nhưng vẫn cần .bash_profile

    Ward khép lại lập luận bằng một vế ngược: bạn cũng cần một .bash_profile nếu có lúc nào đó bạn muốn đăng nhập trên console hoặc từ xa, vì những shell đăng nhập ấy không bao giờ bận tâm tới .bashrc.1 Hai vế cộng lại chính là lý do của mẹo “một tệp, một liên kết”.

    Liên kết hay một dòng?

    Ông đưa hai cách hiện thực tương đương: chia sẻ tệp .bashrc với .bash_profile qua một liên kết tượng trưng, hoặc làm quan hệ ấy rõ ràng hơn bằng cách tạo .bash_profile chỉ gồm một dòng: . $HOME/.bashrc.1 Tài liệu bash cũng ghi đúng khuôn mẫu này như cách làm điển hình: if [ -f ~/.bashrc ]; then . ~/.bashrc; fi.2

  4. example .bashrc

    Tệp mẫu — và phép kiểm tra $- Một tệp mẫu rất ngắn The example file — and the $- test

    Để thoả mãn cả shell đăng nhập lẫn không đăng nhập, Ward đưa ra một ví dụ mà ông gọi là “rất sơ đẳng, nhưng hoàn toàn đủ dùng”: đặt đường dẫn lệnh (với $HOME/bin ở phía trước để các tệp thực thi ở đó được ưu tiên hơn phiên bản hệ thống), đặt PS1='\u\$ ', đặt EDITOR và VISUAL thành vi, PAGER thành less, LESS=meiX, rồi export các biến môi trường ấy, và cuối cùng là umask 022.1

    Tệp mẫu của tác giả chỉ có mấy dòng: chỗ tìm lệnh, dấu nhắc, chương trình sửa văn bản, chương trình xem văn bản, và quyền mặc định. Thế thôi. Nhớ nhé: một tệp tốt có thể chỉ dài bằng nửa màn hình.

    To satisfy both non-login and login shells, Ward gives an example he calls "very elementary (yet perfectly sufficient)": set the command path (with $HOME/bin at the front so executables there take precedence over the system versions), set PS1='\u\$ ', set EDITOR and VISUAL to vi, PAGER to less, LESS=meiX, then export those environment variables, and finally umask 022.1

    Bạn gặp nó ở đâuWhere you meet it Khi bạn dựng một máy mới và muốn một tệp khởi động đủ chạy ngay mà không cần chép từ máy cũ. Khi bạn muốn bắt đầu lại từ một tệp sạch. When you set up a new machine and want a startup file that just works, without copying one from the old box.

    Vì sao phải export

    Dòng export PATH EDITOR VISUAL PAGER LESS không phải nghi thức thừa: Ward chú thích thẳng trong tệp mẫu rằng “bạn phải export các biến môi trường”.1 Không export thì chúng chỉ là biến của riêng shell hiện tại và không đi theo các chương trình bạn khởi chạy.

    EDITOR, VISUAL, PAGER nghĩa là gì

    Chú thích của Ward trong tệp mẫu: EDITOR và VISUAL quyết định trình soạn thảo mà các chương trình như less và trình thư điện tử gọi khi được yêu cầu sửa một tệp; PAGER là trình xem tệp văn bản mặc định cho những chương trình như man.1 Trang environ(7) mô tả cùng quy ước ở mức hệ thống: PAGER là tiện ích người dùng ưa dùng để hiển thị tệp văn bản, EDITOR/VISUAL là tiện ích ưa dùng để sửa tệp văn bản.5

    LESS=meiX và biến thể FRX

    Ward đưa LESS=meiX và ghi một kiểu khác là LESS=FRX, chú thích ngay trong tệp: F = thoát khi hết nội dung, R = hiện ký tự thô, X = không dùng màn hình thay thế.1 Trang less(1) khớp với từng chữ: -F tự thoát nếu toàn bộ tệp hiển thị vừa màn hình đầu; -R xuất một tập giới hạn các chuỗi thoát ở dạng thô trong khi vẫn giữ đúng bố cục màn hình; -X vô hiệu hoá việc gửi chuỗi khởi tạo/kết thúc termcap tới terminal.12 Các chữ trong meiX cũng có nghĩa xác định: -m nhắc dài kèm phần trăm vị trí, -e tự thoát ở lần chạm cuối tệp thứ hai, -i tìm kiếm bỏ qua phân biệt hoa thường.12

    Tách hành vi login và non-login

    Với một .bashrc trùng khớp .bash_profile, bình thường bạn không chạy lệnh phụ nào cho shell đăng nhập. Nhưng nếu muốn định nghĩa hành động khác nhau, Ward đưa ra một phép kiểm tra thêm vào .bashrc: dùng case $- in để kiểm tra biến $- của shell xem có ký tự i hay không, nhánh *i*) chứa lệnh tương tác, nhánh *) chứa lệnh không tương tác.1 Trang bash(1) lý giải vì sao phép thử ấy hợp lệ: bash đặt PS1 và $- có chứa i nếu shell là tương tác, nên một script hay một tệp khởi động có thể kiểm tra trạng thái này.9

  5. the tcsh shell

    tcsh — một thứ tự đơn giản hơn hẳn tcsh — một shell khác, đơn giản hơn tcsh — a distinctly simpler order

    Ward giới thiệu tcsh là bản csh chuẩn trên hầu như mọi hệ thống Linux — một C shell được tăng cường, đã phổ biến hoá những tính năng như soạn thảo dòng lệnh và hoàn thành tên tệp cùng tên lệnh nhiều chế độ. Ngay cả khi bạn không dùng tcsh làm shell mặc định cho người dùng mới (bash nên là mặc định), bạn vẫn nên cung cấp tệp khởi động tcsh phòng khi người dùng của bạn tình cờ gặp nó.1

    Ngoài bash còn có một shell khác tên tcsh. Nó dễ hơn ở chỗ: chỉ có một tệp để nhớ. Nhớ nhé: tcsh chỉ tìm .tcshrc, không thấy thì tìm .cshrc.

    Ward introduces tcsh as the standard csh on virtually all Linux systems — an enhanced C shell that popularised features such as command-line editing and multi-mode filename and command completion. Even if you don't use tcsh as the default shell for new users (bash should be the default), you should still provide tcsh startup files in case your users happen to come across it.1

    Bạn gặp nó ở đâuWhere you meet it Trên các máy Unix lâu đời hoặc trong các phòng thí nghiệm học thuật, nơi csh vẫn là shell mặc định của nhiều tài khoản. Trên những máy cũ mà người ta vẫn dùng shell kiểu cũ. On long-lived Unix boxes or academic lab machines, where csh is still the default shell on many accounts.

    Thứ tự của tcsh

    Với tcsh, Ward viết, bạn không phải bận tâm về khác biệt giữa shell đăng nhập và không đăng nhập: khi khởi động, tcsh tìm một tệp .tcshrc; nếu không có, nó tìm tệp khởi động .cshrc của csh. Lý do của thứ tự này là để bạn có thể dùng .tcshrc cho những mở rộng của tcsh vốn không chạy trên csh.1 Trang hướng dẫn tcsh mô tả chuỗi đầy đủ: một shell đăng nhập bắt đầu bằng /etc/csh.cshrc và /etc/csh.login, rồi trong thư mục nhà là ~/.tcshrc — hoặc, nếu không tìm thấy, ~/.cshrc — rồi ~/.history, rồi ~/.login, và cuối cùng ~/.cshdirs; shell không đăng nhập chỉ đọc /etc/csh.cshrc và ~/.tcshrc hoặc ~/.cshrc.13

    Lời khuyên: hãy dùng .cshrc

    Ward nghiêng về tệp truyền thống: bạn có lẽ nên dùng .cshrc thay vì .tcshrc, vì rất khó có chuyện ai đó dùng tệp khởi động của bạn với csh — và nếu một người dùng thật sự gặp csh trên hệ thống khác, .cshrc của bạn vẫn chạy được.1

    Tệp .cshrc mẫu

    Tệp mẫu của ông song song với bản bash, chỉ khác cú pháp: setenv PATH $HOME/bin:/usr/local/bin:/usr/bin:/bin, setenv EDITOR vi, setenv VISUAL vi, setenv PAGER less, setenv LESS meiX, umask 022, và dấu nhắc set prompt="%m%% "; chú thích trong tệp liệt kê các phép thay thế: %n tên người dùng, %m tên máy, %/ thư mục hiện tại, %h số hiệu lịch sử, %l terminal hiện tại, %% cho ra dấu %.1 Trang hướng dẫn tcsh xác nhận từng ký hiệu: %/ là thư mục làm việc hiện tại, %m là tên máy tới dấu chấm đầu tiên, %n là tên người dùng, %h là số hiệu sự kiện lịch sử hiện tại, %l là tty của shell, và %% là một dấu phần trăm đơn.13

Cụm khái niệm 04 Concept cluster 04

Mặc định cho người dùng mới, các cạm bẫy, và ranh giới của chương Làm tệp cho người khác dùng Defaults for new users, the pitfalls, and the chapter's boundary

Ward đưa ra một quy trình rất cụ thể thay cho lý thuyết: cách tốt nhất để viết tệp khởi động và chọn mặc định cho người dùng mới là thử nghiệm với một người dùng thử trên hệ thống. Tạo người dùng thử với thư mục nhà trống, và kiềm chế việc chép tệp khởi động của chính bạn vào đó — hãy viết tệp mới từ đầu.1

Muốn biết tệp của mình có tốt không, đừng đoán: tạo một tài khoản thử, để trống hoàn toàn, rồi viết tệp mới từ đầu và đăng nhập thử. Nhớ nhé: thử trên tài khoản mới, đừng thử trên tài khoản của bạn.

Instead of theory, Ward gives a concrete procedure: the best way to write startup files and choose defaults for new users is to experiment with a test user on the system. Create the test user with an empty home directory, and refrain from copying your own startup files there — write the new files from scratch.1

Quy trình. Khi bạn nghĩ mình đã có một thiết lập chạy được, hãy đăng nhập với tư cách người dùng thử mới theo mọi cách có thể — trên console, từ xa, v.v. — và kiểm thử càng nhiều thứ càng tốt, gồm cả hoạt động của hệ thống cửa sổ và các trang hướng dẫn. Khi hài lòng, hãy tạo người dùng thử thứ hai, chép tệp khởi động từ người thứ nhất sang; nếu mọi thứ vẫn chạy, bạn đã có một bộ tệp khởi động mới để phân phát.1

Cách làm. Tạo tài khoản thử, viết tệp mới, đăng nhập thử đủ kiểu. Rồi tạo tài khoản thử thứ hai và chép tệp sang. Nếu vẫn chạy tốt thì mới đem phát. Nhớ nhé: thử hai lần rồi mới phát.

The procedure. When you think you have a working setup, log in as the new test user in all possible ways — on the console, remotely and so on — and test as many things as possible, including windowing-system operation and manual pages. When you're happy, create a second test user, copying the startup files from the first; if everything still works, you now have a new set of startup files you can distribute.1

# sáu điều đừng làm
không lệnh đồ hoạ
không đặt DISPLAY
không đặt kiểu terminal
không tiếc lời chú thích
không in ra stdout
không đặt LD_LIBRARY_PATH

Đừng mở cửa sổ đồ hoạ
Đừng in chữ ra màn hình
Đừng tiếc ghi chú

# six things not to do
no graphical commands
no DISPLAY
no terminal type
no skimping on comments
nothing printing to stdout
never LD_LIBRARY_PATH

  1. shell defaults

    Shell mặc định — bốn lý do chọn bash Chọn shell nào cho người mới Shell defaults — four reasons to choose bash

    Ward khẳng định shell mặc định cho mọi người dùng mới trên hệ thống Linux nên là bash, và đưa bốn lý do: người dùng tương tác với cùng một shell mà họ dùng để viết script (ông nói thêm, với nhiều lý do không triển khai ở đây, csh là công cụ viết script dở tệ khét tiếng); bash là mặc định trên các bản phân phối Linux; bash dùng thư viện GNU readline để nhận đầu vào, nên giao diện của nó giống hệt nhiều công cụ khác; và bash cho bạn quyền kiểm soát tinh tế, dễ hiểu đối với chuyển hướng vào/ra cùng các file handle.1

    Cho người mới thì chọn bash. Lý do đơn giản: nó là mặc định ở gần như mọi nơi, và bạn viết script bằng chính nó. Nhớ nhé: không biết chọn gì thì chọn bash.

    Ward states the default shell for any new user on a Linux system should be bash, and gives four reasons: users interact with the same shell they use to write shell scripts (he adds that, for many reasons he won't expand on, csh is a notoriously bad scripting tool); bash is the default on Linux distributions; bash uses the GNU readline library to accept input, so its interface is identical to that of many other tools; and bash gives you fine, easy-to-understand control over I/O redirection and file handles.1

    Bạn gặp nó ở đâuWhere you meet it Khi bạn nhận ra tổ hợp phím sửa dòng lệnh trong psql hay python giống hệt trong shell — đó là readline đang làm việc. Khi các phím mũi tên và phím sửa dòng hoạt động giống nhau ở nhiều chương trình. When you notice the line-editing keys in psql or python behave exactly as in the shell — that's readline at work.

    readline là một thư viện dùng chung

    Lý do thứ ba của Ward có cơ sở kỹ thuật rõ ràng: GNU Readline là một thư viện độc lập cung cấp khả năng soạn thảo dòng lệnh và lịch sử cho các chương trình tương tác, được nhiều dự án nhúng vào chứ không riêng bash.14 Trang bash(1) cũng cho phép tắt nó qua tuỳ chọn --noediting, tức là “không dùng thư viện GNU readline để đọc dòng lệnh khi shell là tương tác”.9

    Tự do chọn, nhưng có mặc định

    Ward không giáo điều: nhiều phù thuỷ Unix lão luyện dùng csh hay tcsh chỉ vì đó là thứ họ quen và không chịu nổi việc đổi; dĩ nhiên bạn có thể chọn shell nào bạn thích, nhưng hãy chọn bash nếu bạn không có sở thích riêng, và dùng bash làm shell mặc định cho mọi người dùng mới — người dùng có thể tự đổi shell bằng lệnh chsh.1 Trang chsh(1) xác nhận công dụng: nó dùng để đổi shell đăng nhập của bạn, và nếu không đưa shell trên dòng lệnh thì nó sẽ hỏi.15

    Những shell khác

    Ward ghi chú rằng còn nhiều shell khác ngoài kia — rc, ksh, zsh, es và nhiều nữa; một số không phù hợp làm shell cho người mới bắt đầu, nhưng zsh và fish đôi khi được người mới ưa chuộng khi họ đi tìm một lựa chọn thay thế.1

  2. editor and pager

    Trình soạn thảo và trình phân trang mặc định Chọn chương trình sửa và xem văn bản The default editor and pager

    Trên các hệ thống truyền thống, trình soạn thảo mặc định là vi hoặc emacs — đây là những trình duy nhất gần như chắc chắn tồn tại (hoặc ít nhất là có sẵn để cài) trên hầu hết mọi hệ Unix, nghĩa là về lâu dài chúng gây ít rắc rối nhất cho người dùng mới. Tuy nhiên, các bản phân phối Linux thường cấu hình nano làm mặc định, vì nó dễ dùng hơn cho người mới bắt đầu.1 Về trình phân trang, ông gọn ghẽ: đó là chương trình hiển thị văn bản từng trang một, như less, và đặt biến môi trường PAGER mặc định thành less là hoàn toàn hợp lý.1

    Chương trình sửa văn bản mặc định thường là vi, nhưng nhiều bản Linux chọn nano vì dễ hơn cho người mới. Chương trình xem văn bản thì cứ chọn less. Nhớ nhé: mới học thì nano dễ hơn, xem văn bản thì dùng less.

    On traditional systems the default editor is vi or emacs — the only editors virtually guaranteed to exist (or at least be available) on nearly any Unix system, which means they cause the least trouble in the long run for a new user. Linux distributions, however, often configure nano as the default, because it's easier for beginners.1 On the pager he is brisk: it's a program such as less that shows text one page at a time, and it's perfectly reasonable to set the default PAGER environment variable to less.1

    Bạn gặp nó ở đâuWhere you meet it Khi git commit hoặc crontab -e bất ngờ mở một trình soạn thảo bạn không biết cách thoát ra. Khi máy tự mở một chương trình lạ và bạn không biết thoát ra kiểu gì. When git commit or crontab -e suddenly opens an editor you don't know how to quit.

    Cùng một kỷ luật, áp cho trình soạn thảo

    Ward mở rộng nguyên tắc “giữ nhỏ” sang tệp cấu hình của trình soạn thảo: cũng như với tệp khởi động shell, hãy tránh các tệp khởi động trình soạn thảo cỡ lớn. Một dòng set showmatch nho nhỏ trong tệp .exrc — để vi hiển thị dấu ngoặc khớp — thì chưa hại ai bao giờ, nhưng hãy tránh xa bất cứ thứ gì thay đổi đáng kể hành vi hay diện mạo của trình soạn thảo, chẳng hạn tính năng showmode, tự thụt lề, và lề ngắt dòng.1

    Vì sao lời khuyên này không phải chuyện khẩu vị

    Nó là hệ quả trực tiếp của bài toán phân phát: một người dùng mới học vi theo sách vở, rồi ngồi vào một tài khoản có tự thụt lề bật sẵn, sẽ thấy trình soạn thảo cư xử khác mọi tài liệu họ đọc được. Mặc định “lạ” đắt hơn mặc định “thô”, vì nó phá vỡ khả năng tự học.

  3. startup file pitfalls

    Sáu cạm bẫy — danh sách những điều đừng làm Sáu điều đừng làm Six pitfalls — the list of things not to do

    Ward liệt kê sáu điều cần tránh trong tệp khởi động: đừng đặt bất kỳ dạng lệnh đồ hoạ nào vào tệp khởi động shell, vì không phải shell nào cũng chạy trong môi trường đồ hoạ; đừng đặt biến môi trường DISPLAY, vì điều đó có thể khiến phiên đồ hoạ của bạn cư xử sai; đừng đặt kiểu terminal; đừng keo kiệt với chú thích mô tả trong tệp khởi động mặc định; đừng chạy các lệnh in ra đầu ra chuẩn; và không bao giờ đặt LD_LIBRARY_PATH trong tệp khởi động shell.1

    Sáu điều cấm: đừng mở chương trình đồ hoạ, đừng đặt DISPLAY, đừng đặt kiểu terminal, đừng tiếc ghi chú, đừng in chữ ra màn hình, và tuyệt đối đừng đặt LD_LIBRARY_PATH. Nhớ nhé: tệp khởi động phải im lặng làm việc.

    Ward lists six things to avoid in startup files: don't put any kind of graphical command in a shell startup file, since not all shells run in graphical environments; don't set the DISPLAY environment variable, as this can make your graphical session misbehave; don't set the terminal type; don't skimp on descriptive comments in default startup files; don't run commands that print to standard output; and never set LD_LIBRARY_PATH in a shell startup file.1

    Bạn gặp nó ở đâuWhere you meet it Khi scp hay rsync tới một máy bỗng hỏng không rõ lý do — rất hay là vì tệp khởi động ở đầu kia in ra một dòng chữ chào mừng. Khi chép tệp qua mạng bị lỗi vì máy bên kia in ra một dòng chữ thừa. When scp or rsync to a host breaks for no clear reason — very often because the startup file at the far end prints a greeting line.

    Vì sao “đừng in ra stdout” lại nghiêm trọng

    Đây là cạm bẫy dễ xem nhẹ nhất trong sáu cái. Các giao thức chạy qua shell từ xa mong đợi một luồng dữ liệu sạch; một dòng chào mừng vô hại trong tệp khởi động sẽ trộn vào luồng đó. Ward đặt nó ngang hàng với các lỗi khác trong cùng một danh sách, không kèm ngoại lệ nào.1

    LD_LIBRARY_PATH: lý do đầy đủ

    Ward chỉ tới Mục 15.1.3 cho chi tiết,1 và ở đó ông gọi biến này là “nguyên nhân số một của mọi vấn đề thư viện chia sẻ”: đặt nó thành một tập tên thư mục ngăn cách bằng dấu hai chấm khiến ld.so tìm các thư mục đó trước mọi thứ khác khi tìm thư viện chia sẻ — gây tổn hại hiệu năng lớn, và quan trọng hơn, gây xung đột cùng thư viện không khớp vì trình liên kết lúc chạy sẽ nhìn vào các thư mục ấy cho mọi chương trình. Giải pháp ông đưa ra là wrapper script.4 Trang ld.so(8) mô tả đúng cơ chế: đó là một danh sách thư mục để tìm thư viện ELF lúc thực thi.16

    Ranh giới của chương

    Ward khép chương bằng việc vạch rõ cái ông không bàn: vì quyển sách chỉ nói về hệ thống Linux nền tảng, nó không bao quát tệp khởi động của môi trường cửa sổ — một vấn đề lớn thật sự, vì trình quản lý hiển thị đưa bạn vào hệ thống Linux hiện đại có bộ tệp khởi động riêng, như .xsession, .xinitrc, cùng vô vàn tổ hợp các mục liên quan tới GNOME và KDE.1 Ông cũng nói rằng các lựa chọn cửa sổ có thể trông rối rắm, và không có một cách chung nào để khởi động môi trường cửa sổ trong Linux — chương kế tiếp mô tả một số khả năng.1

    Cùng một kỷ luật cho GUI

    Lời dặn cuối cùng của ông đóng vòng tròn với mục tiêu Simplicity ở đầu chương: khi đã biết hệ thống của mình làm gì, bạn có thể hơi quá đà với các tệp liên quan tới môi trường đồ hoạ — điều đó không sao, nhưng đừng mang nó sang cho người dùng mới; cùng một nguyên lý giữ mọi thứ đơn giản trong tệp khởi động shell cũng có tác dụng tuyệt vời với tệp khởi động GUI. Thật ra, ông kết luận, bạn có lẽ chẳng cần đổi tệp khởi động GUI của mình chút nào.1

Đính chính Corrections

Ba ngộ nhận mà người đọc lần đầu hay mắc Ba chỗ hay hiểu nhầm Three misconceptions first readers hit

Phần này thuộc mức đọc Đầy đủ: nó đối chiếu điều người đọc thường nghĩ với điều bản văn thật sự nói.

Phần này hơi khó, bạn có thể bỏ qua và quay lại sau. Nhớ nhé: hiểu chậm mà chắc vẫn hơn.

This block belongs to the Đầy đủ (full) reading level: it sets what readers usually assume against what the text actually says.

“Shell đọc tất cả các tệp khởi động của tôi” "The shell reads all of my startup files"

Ngộ nhận: đặt cùng một dòng vào cả .bash_profile lẫn .profile cho chắc ăn, vì shell sẽ đọc cả hai.

Bản văn nói: khi bash chạy như shell đăng nhập, sau /etc/profile nó tìm .bash_profile, .bash_login và .profile, rồi chỉ chạy tệp đầu tiên nó thấy.1 Tài liệu bash thượng nguồn nói chính xác: tệp đầu tiên tồn tại và đọc được.2 Một tệp .bash_profile vô tình tồn tại sẽ âm thầm che khuất toàn bộ .profile của bạn.

Misconception: put the same line in both .bash_profile and .profile to be safe, since the shell reads both.

The text says: when bash runs as a login shell, after /etc/profile it looks for .bash_profile, .bash_login and .profile, and runs only the first one it sees.1 The upstream bash documentation is precise: the first one that exists and is readable.2 A .bash_profile that exists by accident will silently shadow your entire .profile.

“Alias là cách gọn nhất để thêm một tuỳ chọn mặc định” "An alias is the tidiest way to add a default option"

Ngộ nhận: đặt ls thành ls -F là một cải tiến vô hại cho mọi người.

Bản văn nói: Ward gọi đây là “một sai lầm kinh điển”. Tốt nhất thì nó khiến khó gỡ tham số -F khi bạn không muốn; tệ nhất thì nó gây hậu quả nghiêm trọng cho người dùng không hiểu rằng họ không đang dùng tham số mặc định.1 Và vì alias không được truyền xuống shell con,1 cùng lệnh ấy sẽ cư xử khác trong script. Trang bash(1) chốt lại: với hầu hết mọi mục đích, hàm shell được ưa chuộng hơn alias.9

Misconception: aliasing ls to ls -F is a harmless improvement for everyone.

The text says: Ward calls this "one classic mistake." At best it makes the -F argument hard to remove when you don't want it; at worst it has severe consequences for a user who doesn't understand they're not using the default arguments.1 And because aliases aren't passed on to child shells,1 the same command behaves differently inside a script. bash(1) settles it: for almost every purpose, shell functions are preferable to aliases.9

“Thêm dấu chấm vào PATH cho tiện, đặt ở cuối là an toàn” "Adding a dot to PATH is handy, and safe if it's last"

Ngộ nhận: chỉ cần không để . ở đầu PATH thì rủi ro biến mất.

Bản văn nói: Ward nêu rõ rằng ngay cả khi dấu chấm nằm ở cuối đường dẫn, bạn vẫn dễ tổn thương trước kẻ tấn công đoán trước các lỗi gõ nhầm như sl hay ks — bên cạnh ví dụ về con ngựa thành Troy tên ls trong một kho lưu trữ phát tán trên internet. Lý do thứ hai độc lập với an ninh: một dấu chấm trong đường dẫn khiến hành vi của một lệnh thay đổi theo thư mục hiện tại.1

Misconception: as long as . isn't at the front of PATH, the risk disappears.

The text says: Ward is explicit that even with the dot at the end of the path, you'd still be vulnerable to an attacker anticipating typos such as sl or ks — alongside his example of a Trojan horse named ls in an archive distributed on the internet. The second reason is independent of security: a dot in a path means a command's behaviour changes according to the current directory.1

Tự kiểm tra Self-check

Bạn đã nắm môi trường người dùng chưa? Thử trả lời xem nào Do you have the user environment yet?

Trả lời bằng lời của bạn, không tra sách. Nếu một câu khiến bạn ngập ngừng, đó chính là phần bạn nên đọc lại.

Thử trả lời miệng thôi, không cần giở lại. Câu nào bí thì quay lại đọc phần đó nhé. Nhớ nhé: chỗ bí chính là chỗ cần học.

Answer in your own words, without looking back. Whichever question makes you hesitate points at the section you should reread.

  1. Hai mục tiêu thiết yếu khi tạo tệp khởi động cho người khác là gì, và vì sao mục tiêu thứ nhất lại là một ràng buộc kỹ thuật chứ không phải khẩu vị?

    Gợi ý sâu hơn: câu “mỗi mục trong một tệp khởi động chỉ là thêm một thứ nữa có thể hỏng” nói gì về chi phí bảo trì?

  2. Ba thư mục tối thiểu trong đường dẫn lệnh là gì, theo đúng thứ tự — và thứ tự ấy bảo đảm điều gì?

    Gợi ý sâu hơn: cây thư mục nào được dành cho phần mềm cài cục bộ, và vì sao nó phải an toàn trước cập nhật hệ thống?

  3. Vì sao Ward bảo bạn không nên đặt MANPATH?

    Gợi ý sâu hơn: nếu biến ấy đã được đặt, tệp cấu hình của hệ thống có ghi đè lên nó không?

  4. Kể ba nhược điểm của alias mà tác giả nêu, và nói ông đề xuất dùng gì thay thế.

    Gợi ý sâu hơn: vì sao bạn không thể đổi một biến môi trường bằng một shell script?

  5. Khi bash chạy như một shell đăng nhập, nó đọc những tệp nào và theo thứ tự nào? Còn khi là shell không đăng nhập?

    Gợi ý sâu hơn: trong nhóm .bash_profile / .bash_login / .profile, có bao nhiêu tệp được thực thi?

  6. Làm sao để biết shell bạn đang ngồi là shell đăng nhập hay không?

    Gợi ý sâu hơn: phép thử ấy đang đọc cái gì của tiến trình shell?

  7. Hai giá trị umask mà tác giả cho là hợp lý là gì, và mỗi giá trị phù hợp với tình huống nào?

    Gợi ý sâu hơn: vì sao mặt nạ chặt hơn lại có thể gây rắc rối với các daemon chạy dưới dạng người dùng giả?

  8. Vì sao một dòng echo vô hại trong tệp khởi động lại có thể làm hỏng việc sao chép tệp qua mạng?

    Gợi ý sâu hơn: cạm bẫy này đứng ở vị trí nào trong danh sách sáu điều cần tránh?

  1. Tệp có dấu chấm ở đầu tên gọi là gì, và vì sao bạn không thấy chúng?

  2. Kể ba chỗ máy đi tìm lệnh, theo đúng thứ tự.

  3. Alias là gì? Nêu một lý do nên hạn chế dùng nó.

  4. Cửa sổ dòng lệnh “đầu tiên” và cửa sổ “mở thêm” đọc tệp khác nhau thế nào?

  5. umask 022 và umask 077 khác nhau ở điểm gì?

  6. Kể hai điều không nên làm trong tệp khởi động.

  1. What are the two essential goals when creating startup files for other users, and why is the first a technical constraint rather than a matter of taste?

  2. What are the three minimum command-path directories, in order — and what does that order guarantee?

  3. Why does Ward tell you not to set MANPATH?

  4. Name three drawbacks of aliases that the author lists, and say what he proposes instead.

  5. Which files does bash read, and in what order, as a login shell? And as a non-login shell?

  6. How can you tell whether the shell you're sitting in is a login shell?

  7. What are the two umask values the author considers reasonable, and which situation suits each?

  8. Why can one harmless echo in a startup file break a file copy over the network?

Khép lại chương Closing the chapter

Hệ thống và người dùng rốt cuộc vẫn phải gặp nhau ở đâu đó, và chỗ gặp ấy là vài tệp nhỏ trong thư mục nhà của bạn. Hãy giữ chúng ít, ngắn và có chú thích đầy đủ — bởi mỗi mục trong một tệp khởi động chỉ là thêm một thứ nữa có thể hỏng.1

Máy và bạn gặp nhau ở mấy tệp nhỏ trong thư mục nhà. Giữ chúng ngắn và ghi chú rõ, vì thêm một dòng là thêm một chỗ có thể hỏng. Nhớ nhé: viết ít, ghi chú nhiều.

The system and the user have to meet somewhere in the end, and that somewhere is a few small files in your home directory. Keep them few, short and fully commented — because each item in a startup file is just one more thing that can break.1