Tuesday, February 20, 2024

How to Access SMB Shares on Linux: A Step-by-Step Guide

If you're working in a mixed environment where you need to access shared folders (also known as SMB shares) from a Windows machine on your Linux system, you'll find this guide invaluable. SMB, or Server Message Block, is a protocol for sharing files, printers, serial ports, and communications abstractions such as named pipes and mail slots between computers. In this tutorial, we'll walk through the process of accessing an SMB share on a Linux machine, step by step.

Step 1: Installing Required Packages

Before we can mount and access SMB shares, we need to ensure our Linux system has the necessary tools. The cifs-utils package provides utilities for mounting SMB/CIFS shares on a Linux system. To install this package, open a terminal and enter the following command:

sudo apt install cifs-utils


sThis command works for Debian-based distributions like Ubuntu. If you're using a different distribution, you might need to use a different package manager, such as yum for Fedora/RHEL or zypper for openSUSE.

Step 2: Creating a Local Mount Directory

Next, we'll create a local directory where the SMB share will be mounted. This is akin to assigning a drive letter to a network share in Windows. While you can choose any location for this directory, a common practice is to use the /mnt directory as a base. Let's create a subdirectory under /mnt for our SMB share. You can replace smb with any name that is meaningful to you. Run the following command:

sudo mkdir /mnt/smb


Step 3: Mounting the SMB Share

Now, we're ready to mount the SMB share to the directory we created in the previous step. To do this, use the following syntax:

sudo mount -t cifs -o username=user, uid=1000,gid=1000,file_mode=0777,dir_mode=0777 //smb-server-address/share-name /mnt/smb

Here's a breakdown of the command:
  • -t cifs: Specifies the type of file system. CIFS is a version of the SMB protocol.
  • -o username=user: Specifies the username required to access the SMB share. Replace user with the actual username.
    • uid=1000: This sets the user ID of the owner for the files. You can find your user ID by running id -u [your_username]. If you omit [your_username], it will give you the ID of the current user. Setting this to your user's ID makes the mounted share behave as if it's owned by you, allowing for easier manipulation of files.
    • gid=1000: Similar to uid, this sets the group ID for the files. Use id -g [your_groupname] to find your group's ID. Often, your primary group ID is the same as your user ID.
    • file_mode=0777 and dir_mode=0777: These options set the permissions for files and directories, respectively. 0777 grants read, write, and execute permissions to everyone. Adjust these values based on your security requirements.
  • //smb-server-address/share-name: This is the path to the SMB share. Replace smb-server-address with the IP address or hostname of the SMB server and share-name with the name of the shared folder.
  • /mnt/smb: The local mount point directory we created earlier.

For example, if the username is smbusername, the IP address of the SMB server is 10.0.1.123, and the name of the shared folder is Seq-Data, the command would look like this:

sudo mount -t cifs -o username=smbusername,uid=1000,gid=1000,file_mode=0777,dir_mode=0777 //10.0.1.123/Seq-data /mnt/mysmb


After entering this command, you will be prompted to enter the password for the specified user account. Once authenticated, the SMB share will be accessible from the local mount point directory (in our example).

And there you have it! You can now access files and directories on the SMB share directly from your Linux system as if they were part of your local file system. This method provides a seamless way to integrate Windows shares into your Linux environment, facilitating file sharing and collaboration across different operating systems.

Thursday, February 15, 2024

Resolved - TypeError: Can't implicitly convert non-string objects to strings

When trying to save my adata object:

adata_query_final.write_h5ad("anndata_objects/3_pcls_adata_with_scArches_labels_20240215.h5ad")

I received the following error:

TypeError: Can't implicitly convert non-string objects to strings

Error raised while writing key 'ann_level_2_transfer_uncert' of <class 'h5py._hl.group.Group'> to /

I have these columns in obs matrix which are supposed to float but some mix up there different type of variables for which I could not save the object.

       'ann_level_1_transfer_uncert', 'ann_level_2_transfer_uncert',
       'ann_level_3_transfer_uncert', 'ann_level_4_transfer_uncert',
       'ann_level_5_transfer_uncert',

I checked the type of the variable in the columns using below command:


print(adata_query_final.obs['ann_level_1_transfer_uncert'].apply(type).value_counts())

ann_level_1_transfer_uncert
<class 'numpy.float64'>    11075
<class 'int'>               1754
<class 'float'>               78
Name: count, dtype: int64

Converted all the columns to float with command below:

adata_query_final.obs['ann_level_1_transfer_uncert'] = adata_query_final.obs['ann_level_1_transfer_uncert'].astype(float)
adata_query_final.obs['ann_level_2_transfer_uncert'] = adata_query_final.obs['ann_level_2_transfer_uncert'].astype(float)
adata_query_final.obs['ann_level_3_transfer_uncert'] = adata_query_final.obs['ann_level_3_transfer_uncert'].astype(float)
adata_query_final.obs['ann_level_4_transfer_uncert'] = adata_query_final.obs['ann_level_4_transfer_uncert'].astype(float)
adata_query_final.obs['ann_level_5_transfer_uncert'] = adata_query_final.obs['ann_level_5_transfer_uncert'].astype(float)

Now, i can save the adata without an issue:

adata_query_final.write_h5ad("anndata_objects/3_pcls_adata_with_scArches_labels_20240215.h5ad")