One place for hosting & domains


      How To Enable SFTP Without Shell Access on Ubuntu 20.04


      SFTP stands for SSH File Transfer Protocol, and is a secure way to transfer files between machines using an encrypted SSH connection. Although similar in name, this is a different protocol than FTP (File Transfer Protocol), but SFTP is widely supported by modern FTP clients.

      SFTP is available by default with no additional configuration on all servers with SSH access enabled. Though it’s secure and fairly straightforward to use, one disadvantage of SFTP is that in a standard configuration, the SSH server grants file transfer access and terminal shell access to all users with an account on the system. In many cases, it is more secure to apply granular control over user permissions. For example, you may want to allow certain users to only perform file transfers, but prevent them from gaining terminal access to the server over SSH.

      In this tutorial, you’ll set up the SSH daemon to limit SFTP access to one directory with no SSH access allowed on a per-user basis.


      To follow this tutorial, you will need access to an Ubuntu 20.04 server. This server should have a non-root user with sudo privileges, as well as a firewall enabled. For help with setting this up, follow our Initial Server Setup Guide for Ubuntu 20.04.

      Step 1 — Creating a New User

      First, create a new user who will be granted only file transfer access to the server. Here, we’re using the username sammyfiles, but you can use any username you like:

      You’ll be prompted to create a password for the account, followed by some information about the user. The user information is optional, so you can press ENTER to leave those fields blank.

      You have now created a new user that will be granted access to the restricted directory. In the next step, you’ll create the directory for file transfers and set up the necessary permissions.

      Step 2 — Creating a Directory for File Transfers

      In order to restrict SFTP access to one directory, you first have to make sure the directory complies with the SSH server’s permissions requirements, which are very particular.

      Specifically, the directory itself and all directories before it in the filesystem tree must be owned by root and not writable by anyone else. Consequently, it’s not possible to give restricted access to a user’s home directory because home directories are owned by the user, not root.

      Note: Some versions of OpenSSH do not have such strict requirements for the directory structure and ownership, but most modern Linux distributions (including Ubuntu 20.04) do.

      There are a number of ways to work around this ownership issue. In this tutorial, you’ll create and use /var/sftp/uploads as the target upload directory. /var/sftp will be owned by root and will not be writable by other users; the subdirectory /var/sftp/uploads will be owned by sammyfiles, so that user will be able to upload files to it.

      First, create the directories:

      • sudo mkdir -p /var/sftp/uploads

      Set the owner of /var/sftp to root:

      • sudo chown root:root /var/sftp

      Give root write permissions to the same directory, and give other users only read and execute rights:

      Change the ownership on the uploads directory to the user you just created. The following command again uses the example user and group sammyfiles, so be sure to change this if you gave the user you created a different name:

      • sudo chown sammyfiles:sammyfiles /var/sftp/uploads

      Now that the directory structure is in place, you can configure the SSH server itself.

      Step 3 — Restricting Access to One Directory

      In this step, you’ll modify the SSH server configuration to disallow terminal access for sammyfiles but allow file transfer access.

      Open the SSH server configuration file using nano or your favorite text editor:

      • sudo nano /etc/ssh/sshd_config

      Scroll to the very bottom of the file and add the following configuration snippet:


      Match User sammyfiles
      ForceCommand internal-sftp
      PasswordAuthentication yes
      ChrootDirectory /var/sftp
      PermitTunnel no
      AllowAgentForwarding no
      AllowTcpForwarding no
      X11Forwarding no

      Here’s what each directive does:

      • Match User tells the SSH server to apply the following commands only to the specified user. Here, we specify sammyfiles. Again, make sure to update this with your own user’s name, if different.
      • ForceCommand internal-sftp forces the SSH server to run the SFTP server upon login, disallowing shell access.
      • PasswordAuthentication yes allows password authentication for this user.
      • ChrootDirectory /var/sftp/ ensures that the user will not be allowed access to anything beyond the /var/sftp directory.
      • AllowAgentForwarding no, AllowTcpForwarding no. and X11Forwarding no disables port forwarding, tunneling and X11 forwarding for this user, respectively.

      This set of commands, starting with Match User, can be copied and repeated for different users too. Make sure to modify the username in the Match User line accordingly.

      Note: You can omit the PasswordAuthentication yes line and set up SSH key access for increased security. Follow the Copying your Public SSH Key section of the SSH Essentials: Working with SSH Servers, Clients, and Keys tutorial to do so. Make sure to do this before you disable shell access for the user.

      In the next step, we’ll test the configuration by SSHing locally with password access, but if you set up SSH keys, you’ll need access to a computer with the user’s key pair.

      After adding these lines, save and close the file. If you’re using nano, you can do this by pressing CTRL + X, and then Y, and then ENTER.

      To apply the configuration changes, restart the service:

      • sudo systemctl restart sshd

      You have now configured the SSH server to restrict access to file transfer only for sammyfiles. The last step is testing the configuration to make sure it works as intended.

      Step 4 — Verifying the Configuration

      Let’s ensure that our new sammyfiles user can only transfer files. As mentioned previously, SFTP is used to transfer files between machines. You can verify this works by testing a transfer between your local machine and server.

      First, try logging into your server as the user you created in Step 1. Because of the settings you added to the SSH configuration file, this won’t be possible:

      • ssh sammyfiles@your_server_ip

      You’ll receive the following message before being returned to your original prompt:


      • This service allows sftp connections only.
      • Connection to your_server_ip closed.

      This means that sammyfiles can no longer access the server shell using SSH.

      Next, verify if the user can successfully access SFTP for file transfer:

      • sftp sammyfiles@your_server_ip

      Instead of an error message, this command will generate a successful login message with an interactive prompt:


      • Connected to your_server_ip
      • sftp>

      You can list the directory contents using ls in the prompt:

      This will show the uploads directory that was created in the previous step and return you to the sftp> prompt:



      To verify that the user is indeed restricted to this directory and cannot access any directory before it, you can try changing the directory to the previous one:

      This command will not give an error but will list the directory contents as before with no change, proving that the user was not able to switch to the parent directory.

      You have now verified that the restricted configuration works as intended. The newly created sammyfiles user can access the server only using the SFTP protocol for file transfer and has no ability to access the full shell.


      You’ve restricted a user to SFTP-only access to a single directory on a server without full shell access. While this tutorial uses only one directory and one user for brevity, you can extend this example to multiple users and multiple directories.

      The SSH server allows even more complex configuration schemes, including limiting access to groups or multiple users at once, or even limited access to certain IP addresses. You can find examples of additional configuration options and explanations of possible directives in the OpenSSH Cookbook. If you run into any issues with SSH, you can debug and fix them with this troubleshooting SSH series.

      Source link

      How To Use the MongoDB Shell

      The author selected the Open Internet/Free Speech Fund to receive a donation as part of the Write for DOnations program.


      Database systems such as MongoDB are typically used with an external application that connects to the database server and performs operations, such as reading and processing the data or writing new entries. In cases like this, you are not interacting with the database server directly. To perform administrative tasks on the database or execute ad-hoc database queries yourself, though, direct access might be needed.

      That’s where the MongoDB shell comes in. The MongoDB shell is an interactive console you can use to connect to the database server and execute commands on it, allowing you to perform administrative tasks and read, write, or manipulate data directly. The MongoDB shell enables you to connect to the database from a command line prompt and interactively work with it from a terminal window. It also allows you to run external scripts to perform repeated tasks with greater convenience.

      In this tutorial, you’ll use the MongoDB shell to connect to a MongoDB database and query the database interactively. You will also use the built-in help system and autocompletion features included in the shell.


      To follow this tutorial, you will need:

      Note: The linked tutorials on how to configure your server, install, and then secure MongoDB installation refer to Ubuntu 20.04. This tutorial concentrates on MongoDB itself, not the underlying operating system. It will generally work with any MongoDB installation regardless of the operating system as long as authentication has been enabled.

      Step 1 — Connecting to the MongoDB Server

      To open up the MongoDB shell, run the mongo command from your server prompt. By default, the mongo command opens a shell connected to a locally-installed MongoDB instance running on port 27017.

      Try running the mongo command with no additional parameters:

      This will print a welcome message with some information about the server the shell is connected to, as well as what version of MongoDB is installed. The following example indicates that the MongoDB server is running on (a loopback interface representing localhost) on MongoDB’s default port (27017) and running version 4.4.6.


      MongoDB shell version v4.4.6 connecting to: mongodb:// Implicit session: session { "id" : UUID("b9a48dc7-e821-4b09-a753-429eedf072c5") } MongoDB server version: 4.4.6

      Below this message, the MongoDB shell’s prompt — indicated by a greater-than sign — will appear:

      Try listing all the databases available on the server. Type show dbs after the shell prompt and press ENTER:

      Assuming you followed the prerequisite tutorial on How To Secure MongoDB, this command won’t return any output. The reason for this is that, even though the MongoDB server is running and the shell was able to connect to it, you didn’t provide any authentication information. Because of this, you have no access rights to work with any of the server databases and the show dbs command returns nothing.

      Exit the shell by typing:

      The Mongo shell will print a brief goodbye message and return you to the system shell:



      Note: Instead of typing the exit command, an alternative way to close the shell is to press CTRL + C instead.

      Now try reconnecting the MongoDB shell to the database server, but this time provide a username and password to properly authenticate into your MongoDB instance. To do so, you’ll need to provide additional command line parameters, as in the following example:

      • mongo -u AdminSammy -p --authenticationDatabase admin

      This command consists of several parts:

      • -u: this flag sets the username used to authenticate into the MongoDB server. This example specifies the administrative user created in the prerequisite MongoDB security tutorial, AdminSammy. For this tutorial, you can replace this with your own administrative user’s username if different.
      • -p: this flag tells the MongoDB shell to use a password when connecting to the database. You will be prompted to provide a password in the terminal window after you press ENTER.
      • --authenticationDatabase: this option specifies the authentication database of the user you’re logging in as. Typically, administrative accounts are managed in the admin database, but if your user’s authentication database is different, enter that database in place of admin.

      Note: To connect to a MongoDB server running on a different machine than localhost, you can add the -h flag followed by your server’s IP address to the shell command.

      Enter the password set during installation and you’ll once again get access to the shell.

      Now try executing the show dbs command once again:

      This time, the command will return a list of all available databases in the system:


      admin 0.000GB config 0.000GB local 0.000GB

      Because you’ve authenticated as a privileged user, the shell will allow you to run commands on any of these databases.

      Now that you have successfully connected to the MongoDB server using a MongoDB shell, you can move on to learning how to execute commands in the shell.

      Step 2 — Executing Commands

      As with other command line interfaces, the MongoDB shell accepts commands and returns the desired results to standard output. As mentioned previously, in MongoDB shell, all commands are typed into the command prompt denoted with the greater-than sign (>). Pressing ENTER after the command immediately executes it and returns the command output to the screen.

      Most commands in MongoDB database are executed on a database or on a collection in a selected database. The currently-selected database is represented by the db object accessible through the shell. You can check which database is currently selected by typing db into the shell:

      On a freshly-connected shell instance, the selected database is always called test:



      You can safely use this database to experiment with MongoDB and the MongoDB shell. To switch to another database, you can run the use command followed by the new database name. Try switching to a database called fruits:

      The shell will inform you that you’re now using the new database:


      switched to db fruits

      You can verify this by typing db again to find the name of the currently-selected database:

      This time, the output will reflect the new database:



      Notice that you haven’t explicitly created the fruits database. MongoDB allows you to run commands on databases and collections that don’t yet exist; it only creates these structures when an object is first inserted into them. Even though you have successfully changed the current database to fruits, this database does not exist yet.

      Try creating this database by inserting an object into it. The following example outlines how to insert an object into a collection within the database called apples. By adding this object, the operation will create both the fruits database and the apples collection.

      Type the following line into the MongoDB shell and press ENTER. Notice the highlighted collection name (apples):

      Pressing ENTER after an open parenthesis will start a multi-line command prompt, allowing you to enter longer commands in more than one line. The insert command won’t register as complete until you enter a closing parenthesis. Until you do, the prompt will change from the greater-than sign to an ellipsis (...).

      You don’t need to break up MongoDB commands into multiple lines like this, but doing so can make long commands easier to read and understand.

      On the next line, enter the object within a pair of curly brackets ({ and }). This example document has only one field and value pair:

      When you once again press ENTER, another line prompt will be shown, allowing you to add further command parameters, like other documents or any specifications allowed by MongoDB’s insert method. For this example, though, you can end your input and run the operation by entering a closing parenthesis and pressing ENTER:

      This time, the Mongo shell will register the ending of the insert command and execute the whole statement.


      WriteResult({ "nInserted" : 1 })

      After inserting this new object into the database, both the fruits database and apples collection will exist. Check the list of available databases with show dbs command:

      Again, this returns a list of all the available databases, but this time the list includes the fruits database:


      admin 0.000GB config 0.000GB fruits 0.000GB local 0.000GB

      To retrieve a list of collections available in the currently-selected database, the show collections command comes in handy:

      Since the fruits database is selected, it will only return the newly-created apples collection:



      With that, you’ve learned how to execute commands in the MongoDB shell. You also created a sample object, which in turn created a new database and a new collection that is now persisted on the server.

      In the final step of this guide, you’ll learn how to invoke the MongoDB shell’s help features to better understand commands and execute them with greater ease.

      Step 3 — Getting Interactive Help from the Shell

      The MongoDB shell has a built-in help system that you can use to get information on database system’s available commands and the objects stored within it. This introductory help screen can be accessed with the help command directly in the shell prompt:

      The MongoDB shell will return a list of more detailed help entries you can use to learn about more specific parts of the shell, as well as with a few examples of most commonly used commands:

      Output help on db methods help on collection methods sharding helpers replica set helpers help admin administrative help help connect connecting to a db help help keys key shortcuts help misc misc things to know help mr mapreduce show dbs show database names show collections show collections in current database show users show users in current database show profile show most recent system.profile entries with time >= 1ms show logs show the accessible logger names show log [name] prints out the last segment of log in memory, 'global' is default use <db_name> set current database db.mycoll.find() list objects in collection mycoll db.mycoll.find( { a : 1 } ) list objects in mycoll where a == 1 it result of the last line evaluated; use to further iterate DBQuery.shellBatchSize = x set default number of items to display on shell exit quit the mongo shell

      The first two entries, highlighted in this example output, illustrate how to execute a help command for the current database and a collection within the current database, respectively. The example collection name given is mycoll, but any valid collection name can be used.

      The last highlighted line — db.mycoll.find() — is an example of one way to retrieve an object from a collection using the find command, which lists objects in a given collection. Because collections are some of the most commonly used structures in a Mongo database, this step will go over how to use Mongo’s find() and help() collection-level methods.

      First, access the apples collection’s help screen to find the commands available for this collection:

      Note: While the initial help command was just help, when executing a help method on database and collection objects you must follow the command with a pair of parentheses so it reads as help() and not just help.

      The output for this command will be lengthy list of available commands you can perform on the apples collection:


      DBCollection help db.apples.find().help() - show DBCursor help db.apples.bulkWrite( operations, <optional params> ) - bulk execute write operations, optional parameters are: w, wtimeout, j db.apples.count( query = {}, <optional params> ) - count the number of documents that matches the query, optional parameters are: limit, skip, hint, maxTimeMS db.apples.countDocuments( query = {}, <optional params> ) - count the number of documents that matches the query, optional parameters are: limit, skip, hint, maxTimeMS . . . db.apples.find([query],[fields]) - query is an optional query filter. fields is optional set of fields to return. e.g. db.apples.find( {x:77} , {name:1, x:1} ) db.apples.find(...).count() db.apples.find(...).limit(n) db.apples.find(...).skip(n) db.apples.find(...).sort(...) . . .

      In addition to the pure list of available commands you can execute on the db.apples collection (each of which are followed by short descriptions of what the given command does), this help screen also gives usage examples for frequently-used commands such as find().

      This bundled help system serves as a useful reference of available commands. You can use it to check your syntax in case you don’t remember the exact spelling or the acceptable fields for a command.

      Since you’ve already learned from the help screens that find() can be used to retrieve objects from a collection, you can now try retrieving the object you created in the apples collection in the previous step.

      However, this example will highlight another of MongoDB’s interactive help aids known as command completion. The MongoDB shell follows the pattern found in other popular shells such as Bash or zsh in which pressing the keyboard’s TAB key will automatically complete whatever command you’re in the process of typing.

      Start by typing the following, but do not press ENTER yet:

      Instead of typing the collection name in full, press the TAB key on the keyboard. The MongoDB shell will respond with the list of all the available possibilities that begin with a:


      > db.a db.adminCommand( db.aggregate( db.apples db.auth(

      This output lists three commands, indicated by an opening parenthesis, as well as the apples collection.

      Type one more letter into the shell:

      Press TAB once more. This time, there are no other possibilities starting with ap and the MongoDB shell will automatically complete the entry and type db.apples for you. Follow the same principle and complete the find() command using TAB completion. Type fi but do not press ENTER:

      Pressing TAB will automatically complete the command name to db.apples.find. At this point, pressing TAB again would cause the shell to list further possibilities, but you can manually add a closing parenthesis to execute the find command:

      The shell will show a list of all the objects found in the apples collection. There will be only one object, the one you inserted previously:


      { "_id" : ObjectId("60f31447f5643f739b0276e9"), "name" : "Red Delicious" }

      With that, you’ve learned how to use the built-in help system and the Mongo shell’s autocomplete feature.


      By reading this article, you will have familiarized yourself with the MongoDB shell. The shell makes it possible to insert new objects into the database, query the existing collections, and perform administrative tasks for managing the database, its data, and its users.

      The MongoDB shell exposes direct access to most of Mongo’s features, such as database and collection objects and methods, making it the primary tool to interactive with a database server. However, the same set of functions and methods can be used when working with MongoDB programmatically, either through MongoDB shell scripting or through the drivers MongoDB has made available for many programming languages.

      You can execute commands from other articles in this series in the MongoDB shell following the principles described in this tutorial. We encourage you to learn more about MongoDB Shell in the official MongoDB documentation.

      Source link

      Como ler e definir variáveis de ambiente e de shell no Linux


      Ao interagir com seu servidor através de uma sessão do shell, há muitas informações compiladas pelo seu shell para determinar o seu comportamento e acesso a recursos. Algumas dessas configurações estão contidas nas definições de configuração enquanto outras são determinadas pela entrada do usuário.

      Uma das maneiras pela qual o shell mantém o controle de todas essas configurações e detalhes é através de uma área mantida por ele chamada ambiente. O ambiente é uma área que o shell compila toda vez que inicia uma sessão que contém variáveis que definem propriedades do sistema.

      Neste guia, vamos discutir como interagir com o ambiente e ler ou definir variáveis de ambiente e de shell interativamente e por arquivos de configuração.

      Como o ambiente e variáveis de ambiente funcionam

      Sempre que uma sessão do shell é gerada, um processo ocorre para coletar e compilar informações que devem estar disponíveis ao processo shell e seus processos filhos. Ele obtém os dados para essas configurações de uma variedade de arquivos e configurações distintas no sistema.

      O ambiente fornece um meio pelo qual o processo shell pode obter ou definir configurações e, por sua vez, passá-las aos seus processos filhos.

      O ambiente é implementado como strings que representam pares de chave-valor. Se múltiplos valores forem passados, eles são normalmente separados por caracteres dois-pontos (:). Cada par será geralmente parecido com isto:


      Se o valor contiver um espaço em branco significativo, as aspas são usadas:

      KEY="value with spaces"

      As chaves nesses cenários são variáveis. Elas podem ser de dois tipos, variáveis de ambiente ou variáveis de shell.

      As variáveis de ambiente são variáveis definidas para a sessão atual do shell e são herdades por qualquer shell ou processo filho. As variáveis de ambiente são usadas para passar informações para processos gerados a partir do shell.

      As variáveis de shell são variáveis contidas exclusivamente no shell no qual foram configuradas ou definidas. Geralmente, elas são usadas para manter o controle de dados efêmeros, como o diretório de trabalho atual.

      Por convenção, esses tipos de variáveis são geralmente definidos usando somente letras maiúsculas. Isso ajuda os usuários a distinguir as variáveis de ambiente em outros contextos.

      Imprimindo variáveis de ambiente e de shell

      Cada sessão do shell mantém o controle de suas variáveis de ambiente e de shell. Podemos acessá-las de algumas maneiras diferentes.

      É possível ver uma lista de todas as nossas variáveis de ambiente usando os comandos env ou printenv. Em seu estado padrão, elas devem funcionar exatamente da mesma maneira:


      SHELL=/bin/bash TERM=xterm USER=demouser LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca:... MAIL=/var/mail/demouser PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games PWD=/home/demouser LANG=en_US.UTF-8 SHLVL=1 HOME=/home/demouser LOGNAME=demouser LESSOPEN=| /usr/bin/lesspipe %s LESSCLOSE=/usr/bin/lesspipe %s %s _=/usr/bin/printenv

      Isso é algo bastante típico para o resultado tanto de printenv quanto env. A diferença entre os dois comandos só é aparente em suas funcionalidades mais específicas. Por exemplo, com printenv, é possível solicitar os valores de variáveis individuais:



      Por outro lado, o env lhe permite modificar o ambiente no qual os programas são executados passando um conjunto de definições de variável em um comando, como este:

      • env VAR1="value" command_to_run command_options

      Considerando que, assim como aprendemos acima, os processos filhos normalmente herdam as variáveis de ambiente do processo pai, isso lhe dá a oportunidade de substituir valores ou adicionar variáveis adicionais ao filho.

      Como você pode ver no resultado do nosso comando printenv, há uma quantidade razoável de variáveis de ambiente configuradas em nossos arquivos e processos de sistema sem a nossa intervenção.

      Esses comandos mostram as variáveis de ambiente, mas como vemos as variáveis de shell?

      O comando set pode ser usado para isso. Se digitarmos set sem nenhum parâmetro adicional, iremos receber uma lista de todas as variáveis de shell, variáveis de ambiente, variáveis locais e funções shell:


      BASH=/bin/bash BASHOPTS=checkwinsize:cmdhist:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:login_shell:progcomp:promptvars:sourcepath BASH_ALIASES=() BASH_ARGC=() BASH_ARGV=() BASH_CMDS=() . . .

      Normalmente, essa é uma lista enorme. Provavelmente, é desejável canalizá-la em um programa pager para manusear mais facilmente todo o resultado:

      A quantidade de informações adicionais recebidas de volta pode parecer muito grande. Provavelmente, não é necessário conhecer todas as funções bash que estão definidas, por exemplo.

      Podemos limpar o resultado especificando que set deve operar no modo POSIX, que não irá imprimir as funções shell. Podemos executá-lo em um subshell para que ele não altere nosso ambiente atual:

      Isso irá listar todas as variáveis de ambiente e de shell que estão definidas.

      Podemos tentar comparar esse resultado com o resultado dos comandos env ou printenv para tentar obter uma lista com apenas as variáveis de shell, mas isso não será perfeito, devido às diferentes maneiras pelas quais esses comandos geram os resultados:

      • comm -23 <(set -o posix; set | sort) <(env | sort)

      Isso provavelmente ainda irá incluir algumas variáveis de ambiente, pois o comando set exibe valores entre aspas, enquanto o printenv e env não colocam os valores de strings entre aspas.

      Isso deve lhe dar uma boa noção das variáveis de ambiente e de shell que estão definidas em sua sessão.

      Essas variáveis são usadas para todo tipo de coisa. Elas oferecem uma forma alternativa de definir valores persistentes para a sessão entre processos, sem gravar alterações em um arquivo.

      Variáveis de ambiente e de shell comuns

      Algumas variáveis de ambiente e de shell são muito úteis e são referenciadas com bastante frequência. Aqui estão algumas variáveis de ambiente comuns que você deve encontrar:

      • SHELL: descreve o shell que irá interpretar todos os comandos que você digitar. Geralmente, isso será bash por padrão, mas outros valores podem ser definidos caso prefira outras opções.
      • TERM: especifica o tipo de terminal a ser emulado ao executar o shell. Diferentes terminais de hardware podem ser emulados para diferentes requisitos de operação. Normalmente, não será necessário se preocupar com isso.
      • USER: o usuário que está atualmente conectado.
      • PWD: o diretório de trabalho atual.
      • OLDPWD: o diretório de trabalho anterior. Isso é mantido pelo shell para retornar ao seu diretório anterior executando cd -.
      • LS_COLORS: define códigos de cor que são usados para adicionar um resultado de cor opcional ao comando ls. Isso é usado para distinguir diferentes tipos de arquivos e fornecer mais informações ao usuário em um olhar rápido.
      • MAIL: o caminho para a caixa de correio do usuário atual.
      • PATH: uma lista de diretórios que o sistema irá verificar ao procurar por comandos. Quando um usuário digita um comando, o sistema irá verificar diretórios neste pedido para o executável.
      • LANG: a configuração atual de idioma e localização, incluindo a codificação de caracteres.
      • HOME: o diretório base do usuário atual.
      • _: o comando executado anteriormente mais recente.

      Além dessas variáveis de ambiente, algumas variáveis de shell que você verá com frequência são:

      • BASHOPTS: a lista de opções que foram usadas quando o bash foi executado. Isso pode ser útil para descobrir se o ambiente do shell irá operar da maneira que você deseja.
      • BASH_VERSION: a versão do bash sendo executada, de forma legível por humanos.
      • BASH_VERSINFO: a versão do bash, em saída legível por máquina.
      • COLUMNS: o número de colunas de largura que estão sendo usadas para exibir um resultado na tela.
      • DIRSTACK: a pilha de diretórios que estão disponíveis com os comandos pushd e popd.
      • HISTFILESIZE: número de linhas de histórico de comando armazenadas em um arquivo.
      • HISTSIZE: número de linhas de histórico de comando permitidas na memória.
      • HOSTNAME: o nome de host do computador neste momento.
      • IFS: o separador de campo interno para separar entradas na linha de comando. Por padrão, é um espaço.
      • PS1: a de definição de prompt de comando primário. Isso é usado para definir a aparência do seu prompt quando inicia a sessão do shell. O PS2 é usado para declarar prompts secundários para quando um comando ocupa várias linhas.
      • SHELLOPTS: opções de shell que podem ser definidas com a opção set.
      • UID: o UID do usuário atual.

      Definindo variáveis de ambiente e de shell

      Para entender melhor a diferença entre as variáveis de ambiente e de shell, e para apresentar a sintaxe para definir essas variáveis, faremos uma pequena demonstração.

      Criando variáveis de shell

      Vamos começar definindo uma variável de shell dentro de nossa sessão atual. Isso é de fácil execução. Precisamos especificar apenas um nome e um valor. Vamos aderir à convenção de manter todas as letras maiúsculas para o nome da variável e defini-las em uma string simples.

      Aqui, usamos aspas, pois o valor de nossa variável contém um espaço. Além disso, usamos aspas simples, pois o ponto de exclamação é um caractere especial no bash do shell que normalmente expande para o histórico do bash se não forem colocados caracteres de escape ou colocado entre aspas simples.

      Agora, temos uma variável de shell. Essa variável está disponível em nossa sessão atual, mas não será passada para processos filhos.

      Podemos ver isso usando o grep para nossa nova variável dentro do resultado de set:


      TEST_VAR='Hello World!'

      Podemos verificar se essa não é uma variável de ambiente testando a mesma coisa com o printenv:

      Nenhum resultado deve ser retornado.

      Vamos aproveitar isso como uma oportunidade para demonstrar uma maneira de acessar o valor de qualquer variável de ambiente ou de shell.


      Hello World!

      Como você pode ver, faça referência ao valor de uma variável executando-a com um sinal de $. O shell recebe isso e entende que deve substituir o valor da variável quando se depara com isso.

      Então, agora, temos uma variável de shell. Ela não deve ser passada para nenhum processo filho. Podemos gerar um novo shell do bash de dentro do atual para demonstrar isso:

      Se digitarmos bash para gerar um shell filho e então tentarmos acessar o conteúdo da variável, nada será retornado. Isso é exatamente o que esperávamos.

      Volte para o nosso shell original digitando exit:

      Criando variáveis de ambiente

      Agora, vamos transformar nossa variável de shell em uma variável de ambiente. Podemos fazer isso exportando a variável. O comando para isso é nomeado apropriadamente:

      Isso irá alterar nossa variável para uma variável de ambiente. Podemos verificar isso olhando nossa listagem de ambiente novamente:


      TEST_VAR=Hello World!

      Desta vez, nossa variável aparece. Vamos tentar nosso experimento com o nosso shell filho novamente:


      Hello World!

      Ótimo! Nosso shell filho recebeu a variável definida pelo seu pai. Antes de sairmos deste shell filho, vamos tentar exportar outra variável. Podemos definir variáveis de ambiente em um único passo, desta forma:

      • export NEW_VAR="Testing export"

      Teste se ele foi exportado como uma variável de ambiente:


      NEW_VAR=Testing export

      Agora, vamos voltar para o nosso shell original:

      Vamos ver se nossa nova variável está disponível:

      Nada é retornado.

      Isso ocorre porque variáveis de ambiente são passadas apenas para processos filhos. Não existe uma maneira integrada de definir variáveis de ambiente do shell pai. Isso é bom na maioria dos casos e impede que os programas afetem o ambiente operacional de onde foram chamados.

      A variável NEW_VAR foi definida como uma variável de ambiente em nosso shell filho. Essa variável estaria disponível para si mesma e qualquer um de seus shells e processos filhos. Quando saímos e voltamos para o nosso shell principal, aquele ambiente foi destruído.

      Rebaixando e removendo variáveis

      Ainda temos nossa variável TEST_VAR definida como uma variável de ambiente. Podemos revertê-la para uma variável de shell digitando:

      Ela não é mais uma variável de ambiente:

      No entanto, ela ainda é uma variável de shell:


      TEST_VAR='Hello World!'

      Se quisermos remover completamente uma variável, seja ela de ambiente ou de shell, podemos fazê-lo com o comando unset:

      Podemos verificar se ela não está mais definida:

      Nada é retornado porque a variável foi removida.

      Definindo variáveis de ambiente no login

      Já mencionamos que muitos programas usam variáveis de ambiente para decidir as especificações de como operar. Não é interessante precisar definir variáveis importantes toda vez que iniciarmos uma sessão do shell. Além disso, já vimos quantas já são definidas no login. Sendo assim, como criamos e definimos variáveis automaticamente?

      Esse é realmente um problema mais complexo do que parece, devido aos inúmeros arquivos de configuração que o shell do bash lê, dependendo de como é iniciado.

      A diferença entre as sessões do shell com login, sem login, interativa e não interativa

      O shell do bash lê arquivos de configuração diferentes dependendo da forma como a sessão é iniciada.

      Uma distinção entre sessões diferentes é se o shell está sendo gerado como uma sessão com login ou sem login.

      Um shell com login é uma sessão de shell que começa pela autenticação do usuário. Se você estiver entrando em uma sessão de terminal ou via protocolo SSH e autenticar-se, sua sessão de shell será definida como um shell com login.

      Se você iniciar uma nova sessão de shell dentro de sua sessão autenticada, como fizemos chamando o comando bash do terminal, uma sessão sem login de shell será iniciada. Seus detalhes de autenticação não foram solicitados quando você iniciou seu shell filho.

      Outra distinção que pode ser feita é se uma sessão de shell é ou não interativa.

      Uma sessão de shell interativa é uma sessão que está anexada a um terminal. Uma sessão de shell não interativa é uma que não está anexada a uma sessão de terminal.

      Dessa forma, cada sessão de shell é classificada como sendo com ou sem login e interativa ou não interativa.

      Uma sessão normal que começa com o SSH é geralmente uma sessão de shell interativa com login. Um script executado a partir da linha de comando é geralmente executado em um shell não interativo e sem login. Uma sessão de terminal pode ser qualquer combinação dessas duas propriedades.

      A classificação da sessão de shell como sendo com ou sem login tem implicações sobre quais arquivos são lidos para inicializar a sessão de shell.

      Uma sessão iniciada como sessão com login lerá detalhes de configuração do arquivo /etc/profile primeiro. Em seguida, ela irá procurar pelo primeiro arquivo de configuração de shell de login no diretório base do usuário para obter detalhes de configuração específicos do usuário.

      Ela lê o primeiro arquivo que achar entre ~/.bash_profile, ~/.bash_login e ~/.profile e não lê nenhum arquivo adicional.

      Em contraste, uma sessão definida como um shell sem login lerá /etc/bash.bashrc e então o arquivo ~/.bashrc específico do usuário para compilar seu ambiente.

      Os shells não interativos leem a variável de ambiente chamada BASH_ENV e o arquivo especificado para definir o novo ambiente.

      Implementando variáveis de ambiente

      Como você pode ver, há uma grande variedade de arquivos diferentes que normalmente precisaríamos observar para colocar nossas configurações.

      Isso oferece uma grande flexibilidade que pode ajudar em situações específicas em que queremos certas configurações em um shell com login e outras configurações em um shell sem login. No entanto, na maior parte do tempo, vamos querer as mesmas configurações em ambas as situações.

      Felizmente, a maioria das distribuições Linux configuram os arquivos de configuração de login para originar os arquivos de configuração sem login. Isso significa que é possível definir as variáveis de ambiente que desejar tanto em arquivos com login, quanto nos sem login. Eles serão então lidos em ambos os cenários.

      Normalmente, vamos definir variáveis de ambiente específicas para cada usuário, e geralmente vamos querer que nossas configurações estejam disponíveis tanto em shells com login quanto sem login. Isso significa que o lugar para definir essas variáveis é no arquivo ~/.bashrc.

      Abra esse arquivo agora:

      Provavelmente, ele já irá conter uma quantidade considerável de dados. A maioria das definições aqui presentes são para definir opções do bash, que não estão relacionadas às variáveis de ambiente. É possível definir variáveis de ambiente da mesma forma que você faria da linha de comando:

      Qualquer nova variável de ambiente pode ser adicionada em qualquer lugar no arquivo ~/.bashrc, desde que não seja colocada no meio de outro comando ou loop for. Em seguida, podemos salvar e fechar o arquivo. Da próxima vez que você iniciar uma sessão do shell, sua declaração de variável de ambiente será lida e transmitida para o ambiente do shell. É possível forçar sua sessão atual a ler o arquivo agora digitando:

      Se precisar definir variáveis em todo o sistema, pense em adicioná-las ao /etc/profile, /etc/bash.bashrc ou /etc/environment.


      As variáveis de ambiente e de shell estão sempre presentes em suas sessões de shell e podem ser muito úteis. Elas são uma maneira interessante para um processo pai definir detalhes de configuração para seus filhos, além de representarem uma maneira de definir opções fora dos arquivos.

      Isso oferece muitas vantagens em situações específicas. Por exemplo, a implantação de alguns mecanismos dependem de variáveis de ambiente para configurar informações de autenticação. Isso é útil, pois não requer a manutenção desses arquivos que podem ser vistos por partes externas.

      Existem muitos outros cenários, mais mundanos e comuns em que você precisará ler ou alterar o ambiente do seu sistema. Essas ferramentas e técnicas devem lhe dar uma boa base para fazer essas alterações e usá-las corretamente.

      Source link